async let - funções assíncronas (async) em Paralelo

Bruno FaganelloBruno Faganello
2 min read

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.

0
Subscribe to my newsletter

Read articles from Bruno Faganello directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Bruno Faganello
Bruno Faganello