Predict the timing
Each fetch suspends for about 1 second and they don't depend on each other. Roughly how long does each version take from start to finish?
Given: fetchA() and fetchB() each await Task.sleep(for: .seconds(1)), then return a string.
Show the code
func fetchA() async -> String {
try? await Task.sleep(for: .seconds(1))
return "A"
}
func fetchB() async -> String {
try? await Task.sleep(for: .seconds(1))
return "B"
}let a = await fetchA()
let b = await fetchB()let (x, y) = await (fetchA(),
fetchB())async let p = fetchA()
async let q = fetchB()
let (r, s) = await (p, q)Hint 1 of 2
Which line actually starts a new child task?
Hint 2 of 2
A tuple's elements are evaluated in order, left to right.
Choose an answer, then open Show answer below to check it.
Show answer
Answer: B V1 2 s · V2 2 s · V3 1 s
Correct. Only async let starts both child tasks before anything is awaited.
V1 and V2 run the calls one after another (about 2 seconds). V3 uses async let, which starts each call as a child task immediately, so both sleep at the same time (about 1 second). For a list of calls whose length is only known at runtime, use a TaskGroup.
Why not the others?
- A V1 2 s · V2 1 s · V3 1 s. The tuple in V2 looks parallel but is not. Its elements are evaluated left to right, and each call is awaited before the next one starts.
- C All 1 s.
awaitsuspends the current task until that call finishes, so V1 runs the calls one after another. - D All 2 s.
async letcreates a child task right away, so both fetches overlap in V3.
Text version
| Version | What runs when | Finishes at |
|---|---|---|
| V1 |
| t = 2.0 s |
| V2 |
| t = 2.0 s |
| V3 |
| t = 1.0 s |