Mobile App Development · Dart/Flutter
Coloque em prática o que viu no conteúdo: Future, async/await, erro assíncrono, Future.wait e Stream.
Exercício
Cria a função buscarNome(), que retorna um Future<String> usando Future.delayed com 300ms de atraso. Em main, await pausa a execução até o Future ser resolvido, para então imprimir o nome carregado.
// Demonstração de Future simples em Dart.
// Future<T> representa um valor que estará disponível no futuro (operação assíncrona).
// 'await' pausa a execução da função até o Future ser resolvido.
// A função que usa 'await' precisa ser marcada como 'async'.
// Simula uma busca assíncrona que retorna um nome após 300ms de delay.
Future<String> buscarNome() {
// Future.delayed() cria um Future que só resolve após o tempo especificado.
// O segundo argumento é uma função que retorna o valor do Future.
return Future.delayed(Duration(milliseconds: 300), () => 'Ana');
}
// main() é 'async' porque usa 'await' para esperar o Future.
Future<void> main() async {
// 'await' pausa a execução até buscarNome() retornar o valor.
// Sem 'await', 'nome' seria um Future<String>, não uma String.
String nome = await buscarNome();
print('Nome carregado: $nome');
}
Saída esperada
Nome carregado: Ana
Como executar
dart run 20-Async_Await/02_Exercicios/codigo_fonte/exercicio_01_future_simples.dart
Exercício
A função buscarMensagem() é marcada com async e usa await Future.delayed(...) internamente. Em main, a primeira linha é impressa imediatamente; só depois dos 300ms de delay é que await buscarMensagem() resolve e a segunda linha aparece.
// Demonstração de funções assíncronas com 'async' e 'await'.
// 'async' marca a função como assíncrona, permitindo usar 'await' dentro dela.
// Funções 'async' sempre retornam um Future, mesmo que o retorno declarado seja String.
// Função assíncrona que simula uma chamada de rede com delay de 300ms.
Future<String> buscarMensagem() async {
// 'await' pausa esta função por 300ms sem bloquear a thread principal.
await Future.delayed(Duration(milliseconds: 300));
// Após o delay, retorna a mensagem normalmente.
return 'Dados recebidos com sucesso';
}
Future<void> main() async {
// Informa ao usuário que a busca começou — exibido antes do delay.
print('Buscando mensagem...');
// 'await' espera buscarMensagem() terminar antes de continuar.
String mensagem = await buscarMensagem();
// Exibido apenas após os 300ms de delay simulado.
print(mensagem);
}
Saída esperada
Buscando mensagem... Dados recebidos com sucesso
Como executar
dart run 20-Async_Await/02_Exercicios/codigo_fonte/exercicio_02_async_await.dart
Exercício
Simula o carregamento de um perfil de usuário retornando um Future<Map<String, dynamic>>. A mensagem "Carregando perfil..." aparece antes do await; o mapa só fica disponível depois do delay, e seus valores são acessados pelas chaves 'nome' e 'nivel'.
// Demonstração de carregamento assíncrono de dados estruturados.
// Simula o carregamento de um perfil de usuário de uma API remota.
// Future<Map<String, dynamic>> retorna um mapa com os dados do perfil.
// Simula a busca de dados de perfil com delay de 300ms (latência de rede).
Future<Map<String, dynamic>> carregarPerfil() async {
// Simula o tempo de resposta de uma chamada de API real.
await Future.delayed(Duration(milliseconds: 300));
// Retorna o mapa com os dados do perfil após o delay simulado.
return {'nome': 'Ana', 'nivel': 'iniciante'};
}
Future<void> main() async {
// Mensagem exibida enquanto aguarda a resposta assíncrona.
print('Carregando perfil...');
// Aguarda o Future e obtém o mapa de dados do perfil.
Map<String, dynamic> perfil = await carregarPerfil();
// Acessa os valores do mapa pelas suas chaves.
print('Nome: ${perfil['nome']}');
print('Nivel: ${perfil['nivel']}');
}
Saída esperada
Carregando perfil... Nome: Ana Nivel: iniciante
Como executar
dart run 20-Async_Await/02_Exercicios/codigo_fonte/exercicio_03_carregamento.dart
Exercício
A função buscarProduto() aguarda 300ms e então lança uma Exception com throw — o que faz o Future ser rejeitado. Em main, o try/catch envolve o await buscarProduto() e captura a exceção normalmente, como em código síncrono.
// Demonstração de tratamento de erros em operações assíncronas.
// Erros em funções 'async' são capturados com try/catch normalmente,
// da mesma forma que em código síncrono.
// Simula uma busca que falha com uma Exception após 300ms.
Future<String> buscarProduto() async {
await Future.delayed(Duration(milliseconds: 300));
// 'throw' em uma função 'async' faz o Future ser rejeitado com a exceção.
throw Exception('Produto nao encontrado');
}
Future<void> main() async {
// try/catch captura exceções lançadas em operações aguardadas com 'await'.
try {
// 'await' recebe o valor resolvido ou propaga a exceção se o Future falhar.
String produto = await buscarProduto();
print(produto);
} catch (erro) {
// Captura a Exception lançada por buscarProduto() e exibe mensagem de erro.
print('Erro ao buscar produto: $erro');
}
}
Saída esperada
Erro ao buscar produto: Exception: Produto nao encontrado
Como executar
dart run 20-Async_Await/02_Exercicios/codigo_fonte/exercicio_04_erro_assincrono.dart
Exercício
buscarUsuario() e buscarPedidos() têm 300ms de latência cada. Future.wait as executa em paralelo — o tempo total é de ~300ms em vez de ~600ms — e retorna uma List<String> com os resultados na mesma ordem em que os Futures foram passados na lista, independentemente de qual terminou primeiro.
// Demonstração de Future.wait para executar múltiplos Futures em paralelo.
// Future.wait recebe uma lista de Futures e aguarda todos concluírem
// simultaneamente — mais eficiente do que aguardá-los um a um com 'await'.
// Simula a busca de dados do usuário (300ms de latência).
Future<String> buscarUsuario() async {
await Future.delayed(Duration(milliseconds: 300));
return 'Usuario carregado';
}
// Simula a busca dos pedidos do usuário (300ms de latência).
Future<String> buscarPedidos() async {
await Future.delayed(Duration(milliseconds: 300));
return 'Pedidos carregados';
}
Future<void> main() async {
// Future.wait executa ambas as funções em paralelo.
// O tempo total é ~300ms (o maior) em vez de ~600ms (somados sequencialmente).
// Retorna uma List<String> com os resultados na mesma ordem da lista de entrada.
List<String> resultados = await Future.wait([
buscarUsuario(),
buscarPedidos(),
]);
// Percorre e exibe cada resultado retornado em paralelo.
for (String resultado in resultados) {
print(resultado);
}
}
Saída esperada
Usuario carregado Pedidos carregados
Como executar
dart run 20-Async_Await/02_Exercicios/codigo_fonte/exercicio_05_future_wait.dart
Exercício
A função geradora contador() usa async* e yield para emitir os números 1, 2 e 3, um a cada 200ms. Em main, await for recebe cada valor assim que ele é emitido e imprime, na ordem, até a Stream se encerrar.
// Demonstração de Stream básica em Dart.
// Stream é uma sequência de eventos assíncronos — valores que chegam ao longo do tempo.
// Diferença de Future: Future resolve uma vez; Stream emite múltiplos valores.
// 'async*' marca uma função geradora assíncrona que usa 'yield' para emitir valores.
// Gera uma Stream que emite os números 1, 2 e 3 com 200ms entre cada emissão.
Stream<int> contador() async* {
for (int numero = 1; numero <= 3; numero++) {
// Aguarda 200ms antes de emitir o próximo valor.
await Future.delayed(Duration(milliseconds: 200));
// 'yield' emite o valor atual para os ouvintes da Stream.
// A função não encerra aqui — continua para a próxima iteração.
yield numero;
}
}
Future<void> main() async {
// 'await for' itera sobre cada valor emitido pela Stream conforme chegam.
// O laço só termina quando a Stream for encerrada (após o último 'yield').
await for (int numero in contador()) {
print('Numero recebido: $numero');
}
}
Saída esperada
Numero recebido: 1 Numero recebido: 2 Numero recebido: 3
Como executar
dart run 20-Async_Await/02_Exercicios/codigo_fonte/exercicio_06_stream_basica.dart