O que é async em Kotlin?

O async é um coroutine builder que inicia uma coroutine e retorna um Deferred<T> — uma promessa de que um resultado vai estar disponível no futuro. Para obter o valor, você chama await().

Enquanto launch é “dispara e esquece”, async é “dispara e pega o resultado depois”. É a ferramenta certa quando você precisa executar tarefas em paralelo e combinar os resultados.

Exemplo básico

import kotlinx.coroutines.*

suspend fun buscarPreco(): Double {
    delay(1000)
    return 49.90
}

suspend fun buscarEstoque(): Int {
    delay(1000)
    return 150
}

fun main() = runBlocking {
    val inicio = System.currentTimeMillis()

    val preco = async { buscarPreco() }
    val estoque = async { buscarEstoque() }

    println("Preço: R$ ${preco.await()}")
    println("Estoque: ${estoque.await()} unidades")
    println("Tempo: ${System.currentTimeMillis() - inicio}ms")
    // Tempo: ~1000ms (paralelo, não 2000ms)
}

As duas chamadas rodam ao mesmo tempo. Se fossem sequenciais, levaria 2 segundos. Com async, leva apenas 1.

Deferred é como um Future

O Deferred funciona de maneira parecida com Future ou Promise de outras linguagens. Ele representa um valor que ainda está sendo calculado.

val resultado: Deferred<String> = async {
    delay(500)
    "Pronto!"
}

// Faz outras coisas enquanto espera...
println(resultado.await()) // Bloqueia só aqui se ainda não terminou

Cuidado com async desnecessário

Um erro comum é usar async seguido de await imediatamente, o que não dá nenhum ganho:

// Ruim — é o mesmo que chamar a função diretamente
val resultado = async { buscarPreco() }.await()

// Bom — executa em paralelo com outra tarefa
val a = async { buscarPreco() }
val b = async { buscarEstoque() }
println("${a.await()} - ${b.await()}")

Tratamento de erros

Se uma exceção acontece dentro do async, ela é propagada quando você chama await():

val resultado = async {
    throw RuntimeException("Deu ruim!")
}

try {
    resultado.await()
} catch (e: Exception) {
    println("Erro: ${e.message}")
}

Use async sempre que precisar paralelizar operações e combinar resultados. É uma das ferramentas mais poderosas do toolkit de coroutines.