Las tareas "hijas" se mantienen dentro de un bloque lo que implica:
- Las tareas se crean y esperan de arriba a abajo.
- Una tarea espera a que su subtareas terminen para poder avanzar.
- Se propagan errores automáticamente: No hay errores opcionales dentro de "closures".
Descargando datos con closures
func fetchData(completion: @escaping (String, Error?) -> Void) {
DispatchQueue.global().asyncAfter(deadline: .now() + 1.0) {
completion("Something", nil)
}
}
func loadData() {
fetchData { data1, error in
guard error == nil else {
print("Manejar error - 1")
return
}
fetchData { data2, error in
guard error == nil else {
print("Manejar error - 2")
return
}
fetchData { data3, error in
guard error == nil else {
print("Manejar error - 3")
return
}
print("Resultado final: \(data1), \(data2), \(data3)")
}
}
}
}
Descargando datos con concurrencia estructurada
func fetchData() async throws -> String {
try await Task.sleep(for: .seconds(1))
return "Data"
}
func loadData() async throws {
let data1 = try await fetchData()
let data2 = try await fetchData()
let data3 = try await fetchData()
print("Resultado final: \(data1), \(data2), \(data3)")
}
Virtudes de la concurrencia estructurada
- El orden de ejecución es claro.
- Es más fácil de mantener.
- Se propaga el error de forma automática.
Top comments (0)