MiddleCodeVery commonNot answered yet
Fetch three endpoints with async let, then N items with a TaskGroup
Implement two fetch helpers over an existing func fetch(_ url: URL) async throws -> Data.
Requirements:
fetchThreeloads three known URLs concurrently and returns them as a tuple.fetchManyloads an arbitrary list of URLs concurrently and returns the data.
func fetchThree(_ a: URL, _ b: URL, _ c: URL) async throws -> (Data, Data, Data) {
// your code here
}
func fetchMany(_ urls: [URL]) async throws -> [Data] {
// your code here
}
Write both implementations.
Bind three known endpoints with async let and read them in one combined await — they run concurrently. For a dynamic N, use a throwing task group: addTask per item, gather with for try await, which rethrows a child error.
- ✗Awaiting each
async letseparately, serializing the fetches - ✗Thinking a
TaskGrouphandles only a fixed compile-time task list - ✗Writing group results into a shared array instead of returning them
- →Why does binding with
async letstart the work before theawait? - →How does a throwing task group propagate one child's error to the parent?
async let starts each fetch at the binding, and the combined await waits for all three. The group scales the same idea to a list of any size:
func fetchThree(_ a: URL, _ b: URL, _ c: URL) async throws -> (Data, Data, Data) {
async let da = fetch(a)
async let db = fetch(b)
async let dc = fetch(c)
return try await (da, db, dc) // all three run concurrently
}
func fetchMany(_ urls: [URL]) async throws -> [Data] {
try await withThrowingTaskGroup(of: Data.self) { group in
for url in urls { group.addTask { try await fetch(url) } }
var out: [Data] = []
for try await data in group { out.append(data) }
return out
}
}
for try await collects results and rethrows the first child failure (which cancels the rest). Group order is completion order; if you need input order, sort by an index.