async let - funções assíncronas (async) em Paralelo
async let faz parte da nova framework de concurrency introduzida pela Apple no Swift.
Com a introdução da nova maneira de realizar chamadas assíncronas no Swift podem surgir algumas duvidas em como executar chamadas em paralelo. O modo "antigo" de ser feito usando os famosos completionHandlers precisávamos utilizar uma classe chamada DispatchGroup()
para conseguirmos realizar esse feito.
Como usar async let
func loadWeather(lat: Double, long: Double, index: Int) async -> Weather {
let url = URL(string: "https://api.openweathermap.org/data/2.5/weather?lat=\(lat)&lon=\(long)&appid=*****")!
let request = URLRequest(url: url)
let (data, _) = try! await URLSession.shared.data(for: request, delegate: nil)
print("Done \(index)")
return try! JSONDecoder().decode(Weather.self, from: data)
}
Temos o nosso código para fazer uma request para nossa API de tempo e retornar nosso modelo. Adicionei um print index para ficar mais fácil a visualização mas isso não é necessário
Do jeito tradicional criaríamos uma função nos moldes a seguir
func getWeather() {
Task {
let saoPaulo = await loadWeather(lat: -23.5489, long: -46.6388, index: 1)
let rio = await loadWeather(lat: -22.9035, long: -43.2096, index: 2)
let bahia = await loadWeather(lat: -11.4098, long: -41.2808, index: 3)
let tempo = [saoPaulo, rio, bahia]
}
}
Se executamos esse código vamos perceber que o nosso log vai estar assim
Done 1
Done 2
Done 3
Se você reparar bem não existe nenhum motivo para executar essas requests em serie, uma não depende da outra e como faríamos isso com async await? Usando o novo termo async let
o código ficará assim:
Task {
async let saoPaulo = loadWeather(lat: -23.5489, long: -46.6388, index: 1)
async let rio = loadWeather(lat: -22.9035, long: -43.2096, index: 2)
async let bahia = loadWeather(lat: -11.4098, long: -41.2808, index: 3)
let tempo = await [saoPaulo, rio, bahia]
}
Percebam que agora só temos um await
e perceba que ele fica posicionado no momento em que tentamos acessar a variável em questão, nesse caso antes de criamos o nosso array.
Se executamos o código agora podemos receber diferentes tipos de log, no meu caso foi:
Done 1
Done 3
Done 2
Lembrando que só o async let só pode ser usado dentro de funções.