MiddleКодОчень частоЕщё не отвечали
Загрузите три эндпоинта через async let, затем N элементов через TaskGroup
Реализуйте два помощника поверх существующей func fetch(_ url: URL) async throws -> Data.
Требования:
fetchThreeзагружает три известных URL параллельно и возвращает их кортежем.fetchManyзагружает произвольный список URL параллельно и возвращает данные.
func fetchThree(_ a: URL, _ b: URL, _ c: URL) async throws -> (Data, Data, Data) {
// ваш код здесь
}
func fetchMany(_ urls: [URL]) async throws -> [Data] {
// ваш код здесь
}
Допишите обе реализации.
Свяжите три известных эндпоинта через async let и прочитайте одним общим await — они идут параллельно. Для динамического N возьмите throwing task group: addTask на элемент, соберите через for try await с пробросом ошибки задачи.
- ✗Ждут каждый
async letотдельно, делая загрузки последовательными - ✗Думают, что
TaskGroupработает только с фиксированным списком задач - ✗Пишут результаты группы в общий массив вместо возврата их из задачи
- →Почему привязка через
async letстартует работу доawait? - →Как throwing task group пробрасывает ошибку одной дочерней задачи родителю?
async let стартует каждую загрузку в момент привязки, а общий await ждёт все три. Группа масштабирует ту же идею на список произвольного размера:
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) // все три идут параллельно
}
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 собирает результаты и пробрасывает первую ошибку дочерней задачи (что отменяет остальные). Порядок в группе — это порядок завершения; если нужен порядок входа, отсортируйте по индексу.