SwiftHTML & CSSSolidityDesenvolvimento de JogosSolana/Rust
17.11.2024

Lição: 53: Confiabilidade em Swift com async/await

Swift introduziu um novo modelo de concorrência com o lançamento do Swift 5.5, oferecendo uma abordagem mais simplificada para lidar com código assíncrono. Este novo modelo utiliza as palavras-chave async e await, facilitando a escrita de código assíncrono limpo e eficiente. Nesta aula, vamos explorar os conceitos básicos da concorrência em Swift e fornecer exemplos para ilustrar seu poder.

O que é Concorrência?

Concorrência é a capacidade de executar múltiplas tarefas ao mesmo tempo. Em Swift, isso é particularmente importante ao lidar com operações que podem demorar, como requisições de rede ou consultas a bancos de dados. O modelo async/await permite que você escreva código assíncrono de uma maneira que se assemelha ao código síncrono, o que ajuda a torná-lo mais fácil de entender e manter.

Conceitos Básicos

Funções Assíncronas

Para definir uma função assíncrona em Swift, utilize a palavra-chave async. Aqui está um exemplo simples:

func buscarDados() async -> String {
    // Simula uma chamada de rede com um atraso
    try? await Task.sleep(nanoseconds: 2_000_000_000) // Dorme por 2 segundos
    return "Dados buscados!"
}

No exemplo acima, buscarDados é uma função assíncrona que simula uma chamada de rede atrasada usando Task.sleep.

Chamando Funções Assíncronas

Para chamar uma função assíncrona, você deve usar a palavra-chave await. Isso informa ao compilador que você está aguardando a operação assíncrona ser concluída.

func carregarConteudo() async {
    let dados = await buscarDados()
    print(dados) // Saída: Dados buscados!
}

Trata de Erros

Quando você lida com operações assíncronas que podem gerar erros, pode combinar async com throws. Aqui está um exemplo:

enum ErroDeDados: Error {
    case erroAoBuscar
}

func buscarDadosComErro() async throws -> String {
    // Simula um erro potencial
    throw ErroDeDados.erroAoBuscar
}

func carregarConteudoComTratamentoDeErros() async {
    do {
        let dados = try await buscarDadosComErro()
        print(dados)
    } catch {
        print("Falha ao buscar dados: \(error)")
    }
}

Grupos de Tarefas

Grupos de tarefas permitem que você crie um grupo de tarefas assíncronas relacionadas que podem ser executadas concorrentemente. Eles fornecem uma maneira de aguardar múltiplas tarefas e coletar seus resultados.

Aqui está um exemplo usando grupos de tarefas:

func buscarMultipleDados() async -> [String] {
    await withTaskGroup(of: String.self) { grupo in
        for i in 1...3 {
            grupo.addTask {
                try await buscarDadosComAtraso(i: i)
            }
        }

        var resultados: [String] = []
        for await resultado in grupo {
            resultados.append(resultado)
        }
        return resultados
    }
}

func buscarDadosComAtraso(i: Int) async throws -> String {
    try await Task.sleep(nanoseconds: UInt64(i) * 1_000_000_000) // Dorme por i segundos
    return "Dados buscados para a tarefa \(i)"
}

@main
struct MeuApp {
    static func main() async {
        let resultados = await buscarMultipleDados()
        print(resultados) // Saída: Dados buscados para a tarefa 1, 2, 3
    }
}

Neste exemplo, buscarMultipleDados cria um grupo de tarefas, gerando múltiplas tarefas assíncronas que buscam dados concorrentemente. Os resultados são coletados e retornados ao final.

Concorrência Estruturada

O modelo de concorrência do Swift também introduz a concorrência estruturada, o que significa que as tarefas assíncronas podem ser definidas dentro de um contexto específico, regulando automaticamente seu ciclo de vida. Isso reduz as chances de vazamentos de recursos e garante que as tarefas sejam concluídas antes de passar para a próxima etapa.

Usando Task

Você pode criar uma Task para executar operações assíncronas:

Task {
    let resultado = await buscarDados()
    print(resultado)
}

Isso cria uma tarefa leve executando em segundo plano, permitindo a execução concorrente.

Conclusão

A concorrência em Swift com async/await simplifica significativamente a maneira como escrevemos código assíncrono. Ela permite que os desenvolvedores escrevam código claro, manutenível e eficiente, enquanto gerenciam a complexidade que vem com a concorrência. Ao entender e utilizar esses recursos, você pode aprimorar suas aplicações Swift, tornando-as mais responsivas e amigáveis ao usuário.

Agora que você possui uma compreensão fundamental do modelo de concorrência do Swift, pode começar a incorporar essas técnicas em seus próprios projetos. Boa codificação!

Video

Did you like this article? Rate it from 1 to 5:

Thank you for voting!