Skip to main content


Programação assíncrona básica


A Programação assíncrona é uma forma de executar tarefas que podem demorar sem travar o restante do programa. Algumas operações não retornam o resultado imediatamente, por exemplo:

  • ler um arquivo grande
  • consultar um banco de dados
  • fazer uma requisição HTTP
  • esperar uma resposta de API
  • salvar dados em disco
  • buscar informações em um servidor

No Dart, essas operações normalmente usam:

  • Future
  • async
  • await


Código síncrono


Antes de entender o assíncrono, veja um exemplo de código síncrono:

void main() {
print('Iniciando sistema');

print('Carregando usuários');

print('Sistema finalizado');
}

Esse código executa linha por linha, se alguma linha precisar receber um dado, o processo para e espera até que esse dado seja fornecido. Isso é execução síncrona.



Problema com tarefas demoradas


Imagine que carregar usuários demore alguns segundos.

void main() {
print('Iniciando sistema');

print('Buscando usuários no banco de dados...');

print('Sistema finalizado');
}

Em um programa real, buscar usuários em banco pode demorar. O programa precisa esperar a resposta antes de continuar usando aqueles dados. É nesse tipo de situação que entra programação assíncrona.



O que é Future


Um Future representa um valor que vai existir no futuro. Uma função que demora para responder pode retornar um Future.

Future<String> buscarUsuario() {
return Future.value('Fulano');
}

A função acima não retorna diretamente uma String. Ela retorna: Future<String>, ou seja, essa função vai entregar uma String no futuro. Comparando com Python, é parecido com uma função async que precisa ser aguardada com await.



Criando um Future com atraso


Podemos simular uma tarefa demorada usando Future.delayed.

Future<String> buscarUsuario() {
return Future.delayed(Duration(seconds: 2), () {
return 'Fulano';
});
}

void main() {
print('Iniciando busca');

buscarUsuario();

print('Fim do programa');
}

A função buscarUsuario() demora 2 segundos para retornar 'Fulano'. Mas nesse exemplo, o main() não espera o resultado. O resultaod desse código é:

Iniciando busca
Fim do programa

O valor 'Fulano' não aparece, porque chamamos a função, mas não aguardamos o resultado.



Usando async e await


Para esperar o resultado de um Future, usamos await. Mas para usar await, a função precisa ser marcada com async.

Future<String> buscarUsuario() {
return Future.delayed(Duration(seconds: 2), () {
return 'Fulano';
});
}

Future<void> main() async {
print('Iniciando busca');

String usuario = await buscarUsuario();

print('Usuário encontrado: $usuario');

print('Fim do programa');
}

O resultaod desse código é:

Iniciando busca
Usuário encontrado: Fulano
Fim do programa

A linha abaixo espera o resultado da função:

String usuario = await buscarUsuario();

Como buscarUsuario() retorna um Future<String>, o await espera esse Future terminar e pega a String final. Sem await, você tem uma promessa de resultado, mas com await, você espera o resultado real.



O que significa async


O async informa que uma função trabalha com código assíncrono.

Future<void> main() async {
// código assíncrono aqui
}

Quando uma função usa async, ela passa a retornar um Future. Por isso o main() ficou assim:

Future<void> main() async {

O void significa que a função não retorna valor, já o Future<void> significa que essa função é assíncrona, ou seja, ela não retorna um valor útil, mas pode demorar para terminar



Future com retorno


Quando uma função assíncrona retorna um valor, o tipo fica assim:

Future<String>
Future<int>
Future<double>
Future<Usuario>
Future<List<Usuario>>

Bem básico essa parte, mas resolvi mostrar porque no começo tudo parece ser bem complicado (até mesmo para mim).