Módulo 9 - Async e asyncio
Corrotinas: async def e await
10 min de leitura · por Cesar Gargiulo, revisado pela equipe ValorFinal e GuardiaSec · Atualizado em 01/07/2026
O que você vai aprender
- Definir uma corrotina com async def.
- Usar await para esperar uma operação assíncrona.
- Entender que chamar uma corrotina devolve um objeto, não o resultado.
- Reconhecer a semelhança entre corrotinas e geradores.
Ouvir o resumo desta aula
Um recap de cerca de 2 minutos na voz do Valim, para ouvir no trânsito ou na academia.
Ler a transcrição do resumo
Resumo da aula: Corrotinas: async def e await.
Os objetivos desta aula. Definir uma corrotina com async def. Usar await para esperar uma operação assíncrona. Entender que chamar uma corrotina devolve um objeto, não o resultado. Reconhecer a semelhança entre corrotinas e geradores.
Veja o essencial, parte por parte.
Escrevendo a primeira corrotina. Uma corrotina é uma função declarada com async def.
Chamar não é executar. Se um print de dentro da corrotina nunca aparece, provavelmente falta o await para executá-la.
Parentes dos geradores. Se as corrotinas soam familiares, não é coincidência.
Esse foi o resumo do essencial. Para se aprofundar, leia a aula completa e responda os exercícios.
Escrevendo a primeira corrotina
Uma corrotina se parece com uma função comum, mas começa com async def em vez de só def. Essa palavrinha muda tudo: a função ganha o poder de pausar no meio, nos pontos marcados com await, e ser retomada depois. Dentro da corrotina, você usa await antes de qualquer operação assíncrona que possa demorar, como uma chamada de rede. No exemplo abaixo usamos asyncio.sleep, a versão assíncrona do sleep, para simular uma espera. A diferença crucial em relação ao time.sleep é que o asyncio.sleep não trava tudo: ele cede o controle ao event loop enquanto espera, deixando outras tarefas avançarem.
import asyncio
async def buscar(nome):
print(f"buscando {nome}")
await asyncio.sleep(1) # espera sem travar o loop
print(f"pronto {nome}")
return f"dados de {nome}"
async def main():
resultado = await buscar("perfil")
print(resultado)
asyncio.run(main())async def cria a corrotina; await espera o asyncio.sleep sem bloquear o event loop.
Chamar não é executar
O erro mais comum de quem começa com async é chamar uma corrotina como se fosse uma função normal e estranhar que nada acontece. Quando você escreve buscar('perfil') sem await, o Python não roda o corpo da corrotina; ele apenas cria e devolve um objeto corrotina, uma promessa de trabalho que ainda não começou. Para o trabalho acontecer de verdade, você precisa aguardar esse objeto com await, se estiver dentro de outra corrotina, ou entregá-lo ao event loop com asyncio.run, se estiver no nível de cima. Esquecer o await é como escrever o pedido num papel e nunca entregá-lo à cozinha.
import asyncio
async def saudar():
await asyncio.sleep(0.5)
return "ola"
async def main():
x = saudar() # NAO executa: x e um objeto corrotina
print(type(x)) # <class 'coroutine'>
resultado = await x # agora sim executa e devolve o valor
print(resultado) # ola
asyncio.run(main())saudar() sozinho só cria o objeto corrotina; é o await que dispara a execução.
Parentes dos geradores
Se as corrotinas soam familiares, não é coincidência. Elas descendem diretamente dos geradores que você viu no módulo 7. Um gerador pausa em cada yield e devolve o controle a quem o consome, retomando de onde parou na próxima chamada. Uma corrotina faz algo muito parecido: pausa em cada await e devolve o controle ao event loop, retomando quando a espera termina. A mecânica de suspender e retomar a execução é a mesma raiz. Entender esse parentesco ajuda a desmistificar o async: não é magia nova, é a velha ideia de uma função que consegue parar no meio e continuar depois, agora coordenada por um event loop.
Na prática, isso significa que o seu código assíncrono lê quase como código normal, de cima para baixo, com os awaits marcando onde ele pode pausar. Você não precisa pensar em callbacks nem em encadear funções; escreve a lógica na ordem natural e apenas sinaliza as esperas. Essa legibilidade é uma das grandes vantagens do async moderno sobre estilos antigos de programação assíncrona. Na próxima aula você conhece o event loop de perto e o asyncio.run, a porta de entrada que faz tudo isso girar.
Teste rápido
O que acontece quando você escreve buscar('x') sem await, sendo buscar uma corrotina?
Perguntas frequentes
- Posso usar await fora de uma função async?
- Não. O await só é válido dentro de uma corrotina, definida com async def. Se você tentar usá-lo em uma função comum ou no nível do módulo, o Python dá erro de sintaxe. A porta de entrada para o mundo assíncrono, a partir de código normal, é o asyncio.run, que você vê na próxima aula.
- Qual a diferença entre asyncio.sleep e time.sleep?
- O time.sleep bloqueia o thread inteiro: nada mais roda durante a pausa. O asyncio.sleep é assíncrono: ele cede o controle ao event loop enquanto espera, então outras corrotinas avançam. Dentro de código async, use sempre asyncio.sleep para não travar o loop.
- Toda função que faz I/O precisa ser async?
- Para participar do modelo assíncrono, sim: as operações de espera devem ter versões que você aguarde com await, oferecidas por bibliotecas assíncronas. Uma chamada bloqueante comum dentro de uma corrotina travaria o event loop. Por isso o ecossistema tem clientes assíncronos próprios para rede, banco e afins.
- Corrotina e gerador são a mesma coisa?
- São parentes próximos, não idênticos. Ambos podem pausar e retomar a execução, o gerador no yield e a corrotina no await. A corrotina é especializada para o modelo assíncrono e trabalha com o event loop. Entender geradores facilita muito a compreensão de corrotinas, porque a mecânica de suspender e continuar é a mesma.
- O que significa o aviso coroutine was never awaited?
- É o Python avisando que você criou um objeto corrotina, chamando a função async, mas nunca o aguardou nem o agendou, então o trabalho não aconteceu. Quase sempre a correção é acrescentar o await que faltou, ou passar a corrotina para asyncio.run ou para uma função como gather.
Fontes
Seu progresso fica salvo neste aparelho. Assinantes sincronizam entre os aparelhos.