
Passo 1 de 7
Distinguir a função do objeto corrotina
Veja a diferença entre definir uma corrotina, chamá-la e obter futuramente seu resultado.
Trilha de aprendizado · Nível 13 · Tutorial 6
Ao concluir, você será capaz de escrever e executar corrotinas simples, distinguindo espera cooperativa de chamadas que bloqueiam o laço de eventos.
Distinguir a função do objeto corrotina
Veja a diferença entre definir uma corrotina, chamá-la e obter futuramente seu resultado. 2 min
Aguardar e usar o resultado com await
Use await para executar uma corrotina chamada, receber seu valor de retorno e utilizá-lo em outra corrotina. 2 min
Executar a entrada assíncrona com asyncio.run
Use asyncio.run para iniciar uma corrotina principal a partir de um arquivo Python executado de forma síncrona. 2 min
Entender a espera cooperativa
Veja quando uma corrotina realmente libera o laço de eventos e por que usar await não cria concorrência por conta própria. 2 min
Prever a sequência de awaits consecutivos
Entenda por que dois awaits escritos em sequência executam uma operação de cada vez. 2 min
Identificar o que bloqueia o laço
Compare espera cooperativa e bloqueio para reconhecer operações que impedem o progresso do laço de eventos. 2 min
Aplicar e revisar em um script completo
Construa e execute um script local que reúne definição de corrotinas, await sequencial, asyncio.run e espera cooperativa. 3 min

Passo 1 de 7
Veja a diferença entre definir uma corrotina, chamá-la e obter futuramente seu resultado.
Assim como def, async def define uma função que pode receber parâmetros e ter return. A diferença é que ela define uma função de corrotina: seu corpo não começa a rodar apenas porque a função foi chamada.
async def buscar_nome(codigo: int) -> str:
print("Consultando dados...")
return f"cliente-{codigo}"
async def cria a função. As instruções do corpo ainda não foram executadas.
Observe a chamada abaixo. Ela cria um objeto corrotina e o guarda em pendente. Nesse momento, nem o print nem o return do corpo aconteceram. Portanto, pendente não contém a string retornada pela função.
pendente = buscar_nome(7)
print(pendente)
# Exibe uma representação de um objeto corrotina.
# "Consultando dados..." ainda não foi exibido.Dica
buscar_nome é a função de corrotina; buscar_nome(7) produz o objeto corrotina; a string "cliente-7" seria o valor retornado quando o corpo fosse executado e concluído. A forma de executar e obter esse valor virá no próximo passo.
Relacione cada elemento à sua descrição.
Toque em um item e depois no par correspondente.

Passo 2 de 7
Use await para executar uma corrotina chamada, receber seu valor de retorno e utilizá-lo em outra corrotina.
Uma chamada como buscar_nome(7) cria um objeto corrotina. Esse objeto é aguardável: ele pode ser usado com await.
Dentro de uma função criada com async def, escreva await buscar_nome(7) para executar essa corrotina e obter o valor de seu return. Assim, o valor recebido pode ser atribuído a uma variável e usado normalmente.

A chamada produz o objeto corrotina; await obtém o valor retornado pelo corpo dela.
Por enquanto, observe apenas a composição. No próximo passo, você verá como iniciar principal a partir de um script síncrono.
async def buscar_nome(codigo):
return f"usuário-{codigo}"
async def principal():
nome = await buscar_nome(7)
mensagem = f"Cadastro encontrado: {nome}"
return mensagemEm principal, a expressão await buscar_nome(7) resulta em "usuário-7". Portanto, nome recebe essa string e mensagem passa a ser "Cadastro encontrado: usuário-7".
await não serve para valores comuns. Por exemplo, await 7 e await "olá" geram erro, porque um inteiro e uma string não são objetos aguardáveis.
Dica
Use await antes de uma expressão que produz um objeto aguardável, como a chamada de uma função definida com async def. No contexto destes scripts, escreva isso dentro de outra função com async def.
Complete a linha dentro de async def principal():
codigo = ____ buscar_codigo()Considere:
async def buscar_nome():
return "Lia"
async def principal():
nome = await buscar_nome()Qual valor é atribuído a nome?

Passo 3 de 7
Use asyncio.run para iniciar uma corrotina principal a partir de um arquivo Python executado de forma síncrona.
Em um script comum, o ponto de entrada é síncrono: o Python começa a executar o arquivo de cima para baixo. Para iniciar uma corrotina nesse contexto, importe asyncio e use asyncio.run(...).
asyncio.run recebe o objeto corrotina criado pela chamada de uma função async, executa essa corrotina em um laço de eventos que ele gerencia e encerra esse laço quando a corrotina termina. Quando asyncio.run retorna, o código síncrono pode continuar.
A chamada da corrotina cria o objeto que será entregue a asyncio.run.

O script entra na parte assíncrona por asyncio.run(...) e volta quando a corrotina principal acaba.
No seu computador, crie um arquivo chamado entrada_async.py e copie o código abaixo. Usar um arquivo .py evita depender de ambientes interativos que podem já estar executando um laço de eventos.
Um programa autocontido com uma entrada assíncrona.
import asyncio
async def buscar_mensagem(nome: str) -> str:
print("Dentro da corrotina")
return f"Olá, {nome}!"
async def principal() -> None:
mensagem = await buscar_mensagem("Ana")
print(mensagem)
if __name__ == "__main__":
print("Antes de asyncio.run")
asyncio.run(principal())
print("Depois de asyncio.run")Exemplo
No terminal, na pasta do arquivo, execute:
python entrada_async.py
A ordem esperada é:
Antes de asyncio.run
Dentro da corrotina
Olá, Ana!
Depois de asyncio.runA expressão principal() não executa imediatamente o corpo de principal: ela produz o objeto corrotina passado para asyncio.run.
Atenção
asyncio.run deve ser usado quando ainda não há um laço de eventos em execução na mesma thread. Chamá-lo de dentro de uma corrotina ou de outro contexto que já tenha um laço ativo gera erro.
Para esta prática, execute o arquivo .py pelo terminal, como no exemplo. Não é necessário criar ou configurar um laço manualmente.
Dica
A proteção if __name__ == "__main__": mantém a entrada do programa explícita: ela chama asyncio.run(principal()) somente quando você executa o arquivo diretamente.
Depois de executar o arquivo, descreva a ordem das mensagens exibidas. Em sua explicação, diga qual é o papel de asyncio.run(principal()) entre os dois print síncronos.
Escreva pelo menos 80 caracteres (0/80).

Passo 4 de 7
Veja quando uma corrotina realmente libera o laço de eventos e por que usar await não cria concorrência por conta própria.
O asyncio usa cooperação: a corrotina em execução precisa chegar a uma oportunidade de suspensão para que o laço de eventos possa dar andamento a outro trabalho que já esteja agendado e pronto.
await é uma possível oportunidade, mas não uma promessa de troca de execução. Se o aguardável já produz seu resultado imediatamente, o await pode terminar sem que a corrotina ceda o controle.
Além disso, uma suspensão não cria trabalho novo nem significa execução paralela: ela apenas deixa o laço disponível durante a espera.
Compare um resultado imediato com uma espera cooperativa.

Um await pode concluir imediatamente ou suspender a corrotina. Apenas no segundo caso o laço fica disponível enquanto ela espera.
Neste exemplo, resposta_imediata() retorna assim que é executada. Portanto, aguardá-la não fornece, por si só, um momento útil de suspensão.
Já await asyncio.sleep(1) simula uma espera de um segundo sem bloquear a thread. Durante esse intervalo, o laço poderia prosseguir com outro trabalho que já tivesse sido agendado. Como este script não agenda outro trabalho, ele apenas retoma pausar() após a espera.
Salve como espera_cooperativa.py e execute com python espera_cooperativa.py.
import asyncio
async def resposta_imediata() -> str:
print("A corrotina imediata começou")
return "pronto"
async def pausar() -> None:
print("Antes da espera cooperativa")
await asyncio.sleep(1)
print("Depois da espera cooperativa")
async def principal() -> None:
valor = await resposta_imediata()
print(f"Resultado: {valor}")
await pausar()
asyncio.run(principal())Dica
asyncio.sleep() é útil para simular uma espera controlada neste tipo de exemplo. Ele não transforma processamento pesado em cooperativo nem cria concorrência sozinho.
Toda expressão com await obrigatoriamente suspende a corrotina atual e faz outra tarefa executar.

Passo 5 de 7
Entenda por que dois awaits escritos em sequência executam uma operação de cada vez.
Quando uma corrotina usa await diretamente em duas chamadas consecutivas, ela só alcança a segunda depois que a primeira termina e devolve seu resultado. Durante a espera cooperativa da primeira, o laço fica livre para trabalho que já exista, mas esse código ainda não iniciou a segunda operação.
A operação B começa somente após o fim de A.

Liberar o laço não cria automaticamente uma segunda operação.
Salve e execute este exemplo em um arquivo Python, se quiser observar a ordem das mensagens.
import asyncio
async def operar(nome: str) -> str:
print(f"início: {nome}")
await asyncio.sleep(1)
print(f"fim: {nome}")
return f"resultado de {nome}"
async def principal() -> None:
primeiro = await operar("A")
segundo = await operar("B")
print(primeiro)
print(segundo)
asyncio.run(principal())Exemplo
A ordem das mensagens é:
início: Afim: Ainício: Bfim: BAs duas esperas simuladas ocorrem uma após a outra. Assim, a duração total tende a ser próxima da soma das esperas, além do pequeno custo do restante do programa. Use a ordem das mensagens como evidência; não dependa de tempos exatos.
Também não há concorrência se você apenas criar os dois objetos antes dos awaits. A chamada cria os objetos, mas seus corpos continuam sem execução até serem aguardados neste exemplo.
async def principal() -> None:
corrotina_a = operar("A")
corrotina_b = operar("B")
primeiro = await corrotina_a
segundo = await corrotina_b
print(primeiro, segundo)Dica
Criar um objeto corrotina não é iniciar a operação. E um await direto interrompe o fluxo desta corrotina até que aquele aguardável termine. Formas explícitas de agendar trabalho serão vistas no próximo tutorial.
No primeiro código, coloque as mensagens na ordem em que aparecem.
Por que operar("B") não começa enquanto operar("A") está em await asyncio.sleep(1) no primeiro código?
Escreva pelo menos 40 caracteres (0/40).

Passo 6 de 7
Compare espera cooperativa e bloqueio para reconhecer operações que impedem o progresso do laço de eventos.
Uma corrotina ainda executa na thread do laço de eventos. Se ela chama uma operação síncrona demorada ou passa muito tempo calculando sem se suspender, essa thread fica ocupada. Enquanto isso, o laço não consegue dar andamento a outro trabalho já agendado.
Compare os dois tipos de espera.

await asyncio.sleep(...) libera o laço durante a espera; uma chamada bloqueante mantém a thread ocupada.
Atenção
Colocar uma chamada bloqueante dentro de async def não a transforma em não bloqueante. E fazer await de uma corrotina que contém essa chamada apenas espera sua conclusão: não libera o laço durante o bloqueio.
Ambas parecem “esperar”, mas afetam o laço de modos diferentes.
import asyncio
import time
async def espera_bloqueante():
print("início bloqueante")
time.sleep(2) # bloqueia a thread do laço
print("fim bloqueante")
async def espera_cooperativa():
print("início cooperativo")
await asyncio.sleep(2) # suspende esta corrotina
print("fim cooperativo")time.sleep(2) mantém a thread parada por 2 segundos. Já await asyncio.sleep(2) suspende a corrotina; nesse intervalo, o laço fica disponível para trabalho que já esteja agendado. Isso não cria trabalho concorrente sozinho nem faz duas chamadas consecutivas deixarem de ser sequenciais.
Dica
Troque time.sleep por await asyncio.sleep quando a espera for artificial, como uma simulação de atraso. Essa troca não resolve uma biblioteca síncrona demorada, leitura/gravação síncrona ou processamento intenso.
O problema não é apenas usar sleep.
async def calcular_total(valores):
total = 0
for valor in valores:
total += valor * valor # muito trabalho aqui pode ocupar o laço
return total
async def carregar_dados():
with open("dados.txt", encoding="utf-8") as arquivo:
return arquivo.read() # entrada síncrona pode demorar
Entrada e saída síncronas demoradas — como acesso a arquivos, rede ou banco de dados por APIs síncronas — podem bloquear. O mesmo vale para cálculos extensos em Python sem oportunidades de suspensão. O próximo tutorial tratará de tarefas; mais adiante, você verá formas apropriadas de integrar trabalho bloqueante.
Uma corrotina usa time.sleep(1) apenas para simular a demora de uma operação. Qual alteração é apropriada?

Passo 7 de 7
Construa e execute um script local que reúne definição de corrotinas, await sequencial, asyncio.run e espera cooperativa.
Crie um arquivo chamado operacoes.py no seu computador. O exemplo usa apenas a biblioteca padrão: cada chamada a consultar simula uma espera cooperativa, retorna um texto e só então a próxima chamada começa.
import asyncio
async def consultar(nome: str) -> str:
print(f"Início: {nome}")
await asyncio.sleep(1)
print(f"Fim: {nome}")
return f"resultado de {nome}"
async def principal() -> None:
primeiro = await consultar("A")
segundo = await consultar("B")
print(primeiro)
print(segundo)
asyncio.run(principal())
Os dois awaits estão em sequência: B só inicia depois que A termina.
No terminal, na pasta onde você salvou o arquivo, execute:
python operacoes.py
A ordem esperada das mensagens é: início de A, fim de A, início de B, fim de B. Depois aparecem os dois valores retornados. Os tempos exatos não são importantes; observe a ordem.
Quais mensagens apareceram e em qual ordem? Inclua os dois valores retornados e explique, em uma frase, por que B não começou antes do fim de A.
Escreva pelo menos 80 caracteres (0/80).
Se a espera simulada fosse escrita com time.sleep(1), a thread do laço ficaria bloqueada durante esse segundo. Para uma espera artificial dentro de uma corrotina, use await asyncio.sleep(1).
Essa troca libera o laço enquanto a corrotina está suspensa, mas não faz A e B virarem operações concorrentes: os awaits em principal continuam consecutivos.
Evite a versão bloqueante abaixo e mantenha a versão cooperativa do script.
# Bloqueia a thread do laço durante a espera:
# import time
# time.sleep(1)
# Suspende cooperativamente esta corrotina:
await asyncio.sleep(1)Por que trocar time.sleep(1) por await asyncio.sleep(1) é importante dentro dessa corrotina? O que permanece igual na ordem entre A e B?
Escreva pelo menos 100 caracteres (0/100).
Resumo
async def define a corrotina; chamá-la produz um objeto que será aguardado.await obtém o retorno da corrotina dentro de outra corrotina.asyncio.run(principal()) é a entrada síncrona do script e gerencia o laço para essa execução.awaits diretos, um após o outro, mantêm as operações sequenciais.await asyncio.sleep(...) é uma espera cooperativa; chamadas síncronas demoradas e processamento longo bloqueiam o laço.Parabéns! Você concluiu: Criar corrotinas com async e await
Milhares de cursos online em vídeo, ebooks e áudiobooks.
Para testar seus conhecimentos no decorrer dos cursos online
Gerado diretamente na galeria de fotos do seu celular e enviado ao seu e-mail
Baixe nosso aplicativo pelo QR Code ou pelos links abaixo:.
+ de 10 milhões
de alunos
Certificado grátis e
válido em todo o Brasil
60 mil exercícios
gratuitos
4,8/5 classificação
nas lojas de apps
Cursos gratuitos em
vídeo, ebooks e audiobooks