Run two API calls concurrently with async let
structured concurrency for parallel work.
use async let to start two independent fetches that run concurrently, then await both, so total time approaches the slower call rather than the sum.
WHAT THIS TESTS This checks whether you understand structured concurrency well enough to overlap independent operations rather than accidentally serializing them, a frequent real-world latency bug.
A GOOD ANSWER COVERS For a fixed, small number of independent calls, async let is the cleanest tool. Writing async let first = fetchA() and async let second = fetchB() starts both child tasks immediately and concurrently; the bindings do not suspend at the point of declaration. You then await them where you need the values, for example let (a, b) = try await (first, second), and combine the results. Because the two requests run in parallel, the total time approaches the duration of the slower one rather than the sum. This differs sharply from the sequential form let a = try await fetchA(); let b = try await fetchB(), where the second request does not even start until the first completes, doubling latency for no reason when they are independent. For a variable or large number of concurrent tasks, use withThrowingTaskGroup, adding a task per item and collecting results, which also gives structured cancellation and error propagation. Both approaches cancel children if the parent is cancelled or one throws.
COMMON WRONG ANSWERS Awaiting the first call before starting the second, serializing them. Reaching for DispatchGroup and completion handlers when async/await is available. Using a detached Task and losing structured cancellation.
LIKELY FOLLOW-UPS When do you prefer a task group over async let? What happens to the other task if one throws? How does cancellation propagate? Is the work truly parallel or just concurrent?
ONE CONCRETE EXAMPLE A profile screen needs the user and their recent posts from two endpoints. With async let user = fetchUser() and async let posts = fetchPosts(), both requests fire at once; let (u, p) = try await (user, posts) waits for both, so a screen that took 600 milliseconds sequentially now takes about 350, the slower call, and if either throws the other is automatically cancelled.
Read the original → developer.apple.com
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.