Structured Concurrency
Structured concurrency means related pieces of work are grouped together neatly, so they all finish (or all get cancelled) as a tidy unit, instead of scattering off on their own.
Syntax
async let first = asyncFunction1()
async let second = asyncFunction2()
let results = await (first, second)
await withTaskGroup(of: ResultType.self) { group in
group.addTask { await work() }
for await result in group { /* use result */ }
}
Concurrent Work with async let
async let starts an asynchronous operation immediately and lets it run concurrently with the rest of the function, until its value is awaited.
Example: Concurrent Work with async let
func fetchFirstName() async -> String {
return "Ada"
}
func fetchLastName() async -> String {
return "Lovelace"
}
async let first = fetchFirstName()
async let last = fetchLastName()
let fullName = await "\(first) \(last)"
print(fullName)
Login to try C/C++/Java/PHP code in the editor
Grouping Tasks with withTaskGroup
withTaskGroup lets you add a dynamic number of child tasks and collect their results together as a structured, awaitable unit.
Example: Grouping Tasks with withTaskGroup
func square(_ n: Int) async -> Int {
return n * n
}
let total = await withTaskGroup(of: Int.self) { group in
for number in 1...4 {
group.addTask {
await square(number)
}
}
var sum = 0
for await result in group {
sum += result
}
return sum
}
print("Sum of squares: \(total)")
Login to try C/C++/Java/PHP code in the editor
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the
view already swaps in the hi_ translation fields (or blanks these
out if untranslated), so this renders correctly for both languages
without a lang_code check here. #}
Common Mistakes
- Launching several independent
Task { }blocks for related work instead of grouping them withasync letor a task group, making cancellation and error propagation harder to manage. - Forgetting
async letbindings run concurrently as soon as declared, but each one must still beawaited to retrieve its result. - Using a task group but forgetting to
awaitall its child tasks before the group'swith...TaskGroupblock ends.
Chapter Summary
async letstarts multiple asynchronous operations concurrently within one function scope.- Each
async letbinding must be awaited to retrieve its value. - Task groups (
withTaskGroup) manage a dynamic number of concurrent child tasks together. - Structured concurrency ties a task's lifetime to the scope that created it, making cancellation and error handling predictable.
🔒
Chapter Quiz — Complete all 6 topics to unlock
0/6 topics done
Complete these topics first: