Async/Await
Concurrent programming made simple
Why Async?
Asynchronous programming allows your code to perform multiple operations concurrently without blocking. This is essential for:
- Network requests (API calls, database queries)
- File I/O operations
- Timer-based operations
- Background processing
Defining Async Functions
Use the async keyword before func:
import stdlib time as t
// Define an async function
async func fetchUserData(userId) {
print("Fetching user", userId, "...")
t.sleep(100) // Simulate network delay
return "User_" + str(userId)
}
// Call with await
user = await fetchUserData(42)
print("Got:", user)
Await Expression
Use await to wait for an async function to complete:
import stdlib time as t
async func slowOperation() {
t.sleep(200)
return "Result after delay"
}
// Await pauses until the result is ready
result = await slowOperation()
print(result) // "Result after delay"
Note
You can only use await at the top level or inside async functions.
Sequential vs Parallel
Sequential Execution
import stdlib time as t
async func fetch(name) {
print("Start:", name)
t.sleep(100)
print("Done:", name)
return name + " data"
}
// These run one after another (sequential)
startTime = t.clock()
result1 = await fetch("API 1")
result2 = await fetch("API 2")
result3 = await fetch("API 3")
elapsed = t.clock() - startTime
print("Total time:", elapsed, "seconds")
// Takes ~300ms (100ms × 3)
Practical Example: Data Pipeline
import stdlib time as t
// Simulate fetching from different sources
async func fetchFromDatabase(query) {
print("DB: Executing query...")
t.sleep(50)
return ["row1", "row2", "row3"]
}
async func fetchFromAPI(endpoint) {
print("API: Calling", endpoint)
t.sleep(80)
return "API response"
}
async func processData(data) {
print("Processing", len(data), "items...")
t.sleep(30)
return "Processed: " + str(len(data)) + " items"
}
// Build a data pipeline
async func runPipeline() {
// Step 1: Fetch raw data
dbData = await fetchFromDatabase("SELECT * FROM users")
print("Got DB data:", dbData)
// Step 2: Enhance with API data
apiData = await fetchFromAPI("/users/enrich")
print("Got API data:", apiData)
// Step 3: Process everything
result = await processData(dbData)
print("Final result:", result)
return result
}
// Run the pipeline
finalResult = await runPipeline()
print("")
print("Pipeline complete:", finalResult)
Error Handling
import stdlib time as t
async func riskyOperation(shouldFail) {
t.sleep(50)
if (shouldFail) {
return "ERROR"
}
return "SUCCESS"
}
// Check result and handle errors
result = await riskyOperation(false)
if (result == "ERROR") {
print("Operation failed!")
} else {
print("Operation succeeded:", result)
}
Task Queue Pattern
import stdlib time as t
// Task queue processing
taskQueue = ["Task A", "Task B", "Task C"]
async func processTask(task) {
print("Processing:", task)
t.sleep(50)
return task + " done"
}
// Process all tasks
results = []
for (task in taskQueue) {
result = await processTask(task)
results.push(result)
}
print("All tasks complete:")
for (r in results) {
print(" -", r)
}