Escreva código assíncrono
Aprenda sobre programação assíncrona em Dart e como fazer requisições HTTP.
Neste capítulo, você vai explorar a programação assíncrona em Dart,
que permite que seus aplicativos executem várias tarefas de forma concorrente.
Você vai aprender a buscar dados da internet usando o pacote http,
para obter um resumo de artigo da Wikipedia.
O que você vai realizar
Pré-requisitos
#-
Ter concluído o Capítulo 2, que abordou a
sintaxe básica do Dart e a interação pela linha de comando.
Você deve ter um projeto
dartpediaconfigurado. - Estar familiarizado com o conceito de APIs (Interfaces de Programação de Aplicações) como uma forma de obter dados.
Tarefas
#
Neste capítulo, você vai modificar o aplicativo CLI dartpedia existente para
buscar e exibir um resumo de artigo
usando
o pacote http e técnicas de programação assíncrona.
Tarefa 1: Adicione a dependência http
#
Antes de fazer requisições HTTP,
você precisa adicionar o pacote http como uma
dependência do seu projeto.
-
Abra o arquivo
dartpedia/cli/pubspec.yamldentro do seu projeto. Esse arquivo se chama pubspec e gerencia os metadados do seu projeto Dart, suas dependências (como o pacotehttp) e seus assets. Localize a seção
dependencies.-
Adicione
http: ^1.4.0(ou a versão estável mais recente) emdependencies. O símbolo^permite que versões compatíveis sejam usadas.cli/pubspec.yamlyamldependencies: http: ^1.4.0 Salve o arquivo
pubspec.yaml.-
Execute
dart pub getno seu terminal, a partir do diretóriodartpedia/cli. Esse comando baixa a dependência recém-adicionada e a deixa disponível para uso no seu projeto.Você deve ver uma saída parecida com esta:
bashResolving dependencies... Downloading packages... + http 1.4.0 lints 5.1.1 (6.0.0 available) Changed 1 dependency! 1 package has newer versions incompatible with dependency constraints. Try `dart pub outdated` for more information.
Tarefa 2: Importe o pacote http
#
Agora que você adicionou o pacote http,
precisa importá-lo no seu arquivo Dart para usar suas funcionalidades.
Abra o arquivo
cli/bin/cli.dart.-
Adicione a seguinte instrução
importno topo do arquivo, junto com o import existente dedart:io:cli/bin/cli.dartdartimport 'dart:io'; import 'package:http/http.dart' as http; // Add this lineEssa linha importa o pacote
httpe dá a ele o aliashttp. Depois disso, você pode se referir a classes e funções do pacotehttpusandohttp.(por exemplo,http.Client,http.get). A parteas httpé uma convenção comum para evitar conflitos de nome caso outra biblioteca importada também tenha uma classe ou função com nome semelhante.
Tarefa 3: Implemente a função getWikipediaArticle
#
Agora, crie uma nova função chamada getWikipediaArticle que
cuida de buscar dados de uma API externa.
Essa função será async, porque
requisições de rede são operações assíncronas.
-
Defina a assinatura da função: Abaixo da sua função
main(e da funçãoprintUsage), adicione a seguinte assinatura de função.cli/bin/cli.dartdart// ... (your existing printUsage() function) Future<String> getWikipediaArticle(String articleTitle) async { //You'll add more code here soon }Destaques do código anterior:
- O tipo de retorno
Future<String>indica que essa função vai, eventualmente, produzir um resultadoString, mas não imediatamente, porque é uma operação assíncrona. - A keyword
asyncmarca a função como assíncrona, permitindo que você useawaitdentro dela.
- O tipo de retorno
-
Construa a URL da API: Dentro da sua nova função
getWikipediaArticle, crie um objetoUri. OUrirepresenta o endpoint da API da Wikipedia que você vai chamar para obter um resumo do artigo.Adicione estas linhas dentro da função
getWikipediaArticle:cli/bin/cli.dartdartFuture<String> getWikipediaArticle(String articleTitle) async { final url = Uri.https( 'en.wikipedia.org', // Wikipedia API domain '/api/rest_v1/page/summary/$articleTitle', // API path for article summary ); // ... } -
Faça a requisição HTTP e trate a resposta: Agora, use a função
getde nível superior dopackage:httppara fazer uma requisição HTTPGETpara a URL que você acabou de construir. A keywordawaitpausa a execução degetWikipediaArticleaté que a chamadagetseja concluída e retorne um objetohttp.Response.Depois que a requisição terminar, verifique o
response.statusCodepara garantir que ela foi bem-sucedida (um status code200significa OK). Se tiver sido bem-sucedida, retorne oresponse.body, que contém os dados obtidos (neste caso, JSON bruto). Se a requisição falhar, retorne uma mensagem de erro informativa.Adicione estas linhas depois da construção do
Uridentro degetWikipediaArticle:cli/bin/cli.dartdartFuture<String> getWikipediaArticle(String articleTitle) async { final url = Uri.https( 'en.wikipedia.org', '/api/rest_v1/page/summary/$articleTitle', ); final response = await http.get(url); // Make the HTTP request if (response.statusCode == 200) { return response.body; // Return the response body if successful } // Return an error message if the request failed return 'Error: Failed to fetch article "$articleTitle". Status code: ${response.statusCode}'; }
Tarefa 4: Integre a chamada da API em searchWikipedia
#
Você vai integrar a chamada da API em searchWikipedia.
Essa função vai conter a lógica principal para tratar o comando wikipedia.
-
Atualize
searchWikipediapara usarasync: Localize sua funçãosearchWikipediae atualize a assinatura para serasync, já que ela agora vai executar operações assíncronas.Sua função
searchWikipediadeve ficar assim:cli/bin/cli.dartdart// ... (your existing main function) void searchWikipedia(List<String>? arguments) async { // Added 'async' final String articleTitle; // If the user didn't pass in arguments, request an article title. if (arguments == null || arguments.isEmpty) { print('Please provide an article title.'); // Read input and provide a default empty string if the input is null. articleTitle = stdin.readLineSync() ?? ''; } else { // Otherwise, join the arguments into a single string. articleTitle = arguments.join(' '); } print('Looking up articles about "$articleTitle". Please wait.'); print('Here ya go!'); print('(Pretend this is an article about "$articleTitle")'); } // ... (your existing printUsage() function)Destaques do código anterior:
void searchWikipedia(List<String>? arguments) async: A função agora éasync. Isso é essencial porque ela vai chamargetWikipediaArticle, que é uma funçãoasynce precisará deawaitno resultado dela.
-
Rejeite entrada
nullou string vazia: Atualmente, se o usuário executardart bin/cli.dart searche pressionar Enter sem digitar um título,stdin.readLineSync()retorna uma string vazia. Se o usuário pressionar Control+D ou Control+Z para enviar um sinal de fim de arquivo (EOF),stdin.readLineSync()retornanull, e?? ''usa uma string vazia como fallback. Nos dois casos, a CLI faz uma requisição simulada à Wikipedia com uma string vazia como título do artigo.Substitua o fallback
?? ''por uma verificação que exibe uma mensagem e encerra a função quando nenhuma entrada válida é fornecida.cli/bin/cli.dartdartvoid searchWikipedia(List<String>? arguments) async { final String articleTitle; if (arguments == null || arguments.isEmpty) { print('Please provide an article title.'); // Read input without the `?? ''` fallback. final inputFromStdin = stdin.readLineSync(); if (inputFromStdin == null || inputFromStdin.isEmpty) { print('No article title provided. Exiting.'); return; // Exit the function if there's no valid input. } articleTitle = inputFromStdin; } else { // Otherwise, join the arguments into a single string. articleTitle = arguments.join(' '); } print('Looking up articles about "$articleTitle". Please wait.'); print('Here ya go!'); print('(Pretend this is an article about "$articleTitle")'); } -
Chame
getWikipediaArticlee exiba o resultado: Substitua as duas linhasprintde placeholder no final desearchWikipediapor uma chamada agetWikipediaArticlee um únicoprintdo resultado.cli/bin/cli.dartdartvoid searchWikipedia(List<String>? arguments) async { final String articleTitle; if (arguments == null || arguments.isEmpty) { print('Please provide an article title.'); final inputFromStdin = stdin.readLineSync(); if (inputFromStdin == null || inputFromStdin.isEmpty) { print('No article title provided. Exiting.'); return; } articleTitle = inputFromStdin; } else { articleTitle = arguments.join(' '); } print('Looking up articles about "$articleTitle". Please wait.'); // Call the API and await the result. var articleContent = await getWikipediaArticle(articleTitle); print(articleContent); // Print the full article response (raw JSON for now) }Destaques do código anterior:
await getWikipediaArticle(articleTitle): ComogetWikipediaArticleé uma funçãoasync, você precisa usarawaitno resultado dela. Isso pausa a funçãosearchWikipediaaté que oFuture<String>retornado porgetWikipediaArticleseja resolvido em umaStringcom o conteúdo do artigo.print(articleContent): Imprime o resumo do artigo obtido como uma string JSON bruta no console.
Tarefa 5: Atualize o main para chamar searchWikipedia
#
Por fim, atualize sua função main para
chamar a nova função searchWikipedia quando
o comando wikipedia for usado.
-
Localize o bloco
else ifna sua funçãomainque atualmente trata o comandosearch. Altere o nome do comando desearchparawikipediae atualize a chamada da função.No código de exemplo,
mainnão usaawaitna chamada asearchWikipedia, o que significa quemainem si não precisa ser marcada comoasync.Sua função
maindeve ficar assim:cli/bin/cli.dartdart// ... (existing const version declaration and printUsage function) void main(List<String> arguments) { if (arguments.isEmpty || arguments.first == 'help') { printUsage(); } else if (arguments.first == 'version') { print('Dartpedia CLI version $version'); } else if (arguments.first == 'wikipedia') { // Changed to 'wikipedia' // Pass all arguments *after* 'wikipedia' to searchWikipedia final inputArgs = arguments.length > 1 ? arguments.sublist(1) : null; searchWikipedia(inputArgs); // Call searchWikipedia (no 'await' needed here for main) } else { printUsage(); // Catch all for any unrecognized command. } }arguments.sublist(1): Isso extrai todos os elementos da listaarguments, começando no segundo elemento (índice 1). Assim, o próprio comandowikipediaé removido, esearchWikipediarecebe apenas os argumentos com o título do artigo.searchWikipedia(inputArgs): Essa linha chamasearchWikipediadiretamente. Comomainnão precisa fazer nada depois quesearchWikipediatermina, você não precisa usarawaitnela a partir demain. Por isso,mainnão precisa serasync.
Tarefa 6: Execute o aplicativo
#
Agora que você implementou a requisição http e
a integrou ao seu aplicativo, teste-o.
-
Abra seu terminal e execute o seguinte comando:
bashdart run bin/cli.dart wikipedia "Dart_(programming_language)" -
Verifique se o aplicativo buscou o resumo do artigo "Dart" na API da Wikipedia e imprimiu o JSON bruto da resposta no console. Você pode ver algo como:
bashLooking up articles about "Dart_(programming_language)". Please wait. { "type": "standard", "title": "Dart (programming language)", "displaytitle": "<span class=\"mw-page-title-main\">Dart (programming language)</span>", "namespace": { "id": 0, "text": "" } // ... (rest of the JSON output will be present but truncated here) } -
Em seguida, tente executar sem argumentos. Por exemplo, quando solicitado, digite "Flutter_(software)".
bashdart run bin/cli.dart wikipediabashPlease provide an article title. Flutter_(software) Looking up articles about "Flutter_(software)". Please wait. { "type": "standard", "title": "Flutter (software)", "displaytitle": "<span class=\"mw-page-title-main\">Flutter (software)</span>", "namespace": { "id": 0, "text": "" } // ... (rest of the JSON output will be present but truncated here) }Você implementou com sucesso o comando
wikipediabásico, que busca dados reais de uma API externa!
Revisão
#O que você concluiu
Aqui está um resumo do que você construiu e aprendeu nesta lição.Dominou futures, async e await
Você aprendeu que Future representa um valor que estará disponível mais tarde. A keyword
async marca funções como assíncronas, e await pausa a execução até que um Future
seja concluído.
Adicionou o pacote http como dependência
Você modificou o pubspec.yaml para adicionar o pacote http, executou dart pub get
para baixá-lo e o importou com um alias (as http). Você pode seguir estes passos para adicionar qualquer pacote externo do pub.dev.
Buscou dados em tempo real da Wikipedia
Você criou getWikipediaArticle() para fazer requisições HTTP GET usando a função get
do package:http, construiu URIs, verificou status codes e retornou o corpo da resposta. Seu CLI agora busca dados reais da web!
Quiz
#Check your understanding
1 / 4-
asyncIsso mesmo!
A palavra-chave
asyncmarca uma função como assíncrona, permitindo que ela useawaitpara esperar operações assíncronas. -
awaitNão exatamente.
awaité usado dentro de funções assíncronas para pausar até o resultado. Ele não marca a função como assíncrona por si só. -
futureNão exatamente.
Futureé um tipo que representa um valor que chegará depois, não uma palavra-chave para marcar funções. -
asynchronousNão exatamente.
Embora seja descritivo,
asynchronousnão é uma palavra-chave do Dart. O Dart usa uma palavra-chave mais curta para marcar funções assíncronas.
Future<String> representa em Dart?
-
Um valor string que estará disponível em algum momento no futuro.
Isso mesmo!
Um
Futureé como uma promise. Ele representa um valor que ainda não está disponível, mas estará assim que uma operação assíncrona (como uma requisição de rede) terminar. -
Uma string que pode ser
null.Não exatamente.
Strings que podem ser nulas têm o tipo
String?. UmFuture<String>representa um valor string que estará disponível depois, quando a operação assíncrona terminar. -
Uma lista de strings que pode crescer com o tempo.
Não exatamente.
Uma lista de strings que pode crescer seria
List<String>.Future<T>encapsula um único valor do tipoT, não uma coleção. -
Uma string armazenada em uma área separada da memória.
Não exatamente.
O tipo
Futurenão tem relação com localização de memória ou armazenamento. Pense no que "future" significa na linguagem do dia a dia.
await faz quando é colocado antes de um Future?
-
Pausa a função até o
Futurecompletar e depois retorna o valor já desencapsulado.Isso mesmo!
O
awaitpausa a execução da função até que oFutureseja concluído. -
Cancela o
Futurese ele demorar demais.Não exatamente.
O
awaitnão cancela nada nem define timeouts. Ele apenas espera, independentemente de quanto a operação demorar. -
Executa o
Futureem uma thread separada para melhorar o desempenho.Não exatamente.
O Dart não usa threads automaticamente dessa forma. O
awaitfunciona dentro do modelo de event loop de thread única do Dart. -
Converte o
Futureem uma operação síncrona.Não exatamente.
A operação continua sendo assíncrona. O
awaitmuda a forma como você escreve o código, não como ele é executado.
await, o que acontece com as outras partes do seu aplicativo?
-
Outras operações assíncronas e handlers de eventos podem continuar rodando.
Isso mesmo!
Esse é o principal benefício da programação assíncrona. Enquanto espera uma operação, o event loop do Dart pode tratar outras tarefas, mantendo seu app responsivo.
-
Tudo trava até a resposta chegar.
Não exatamente.
Se tudo travasse, a programação assíncrona não traria nenhum benefício. Pense em por que a programação assíncrona existe.
-
O Dart inicia automaticamente uma nova thread para cuidar da espera.
Não exatamente.
O Dart usa um modelo de event loop de thread única. O
awaitfunciona dentro desse modelo, sem criar novas threads. -
O programa é encerrado se a resposta demorar demais.
Não exatamente.
Programas não são encerrados por esperar operações assíncronas. Não existe um timeout embutido que cause esse encerramento.
Próxima lição
#No próximo capítulo, você vai focar em organizar nosso código em bibliotecas e pacotes reutilizáveis. Você vai refatorar seu aplicativo para melhorar sua estrutura e manutenibilidade, criando um pacote separado para lidar com argumentos de linha de comando.
Salvo indicação em contrário, a documentação neste site reflete Dart 3.13.7. Página atualizada pela última vez em 2026-11-12. Ver código-fonte ou relatar um problema.
Encontrou essa página sem tradução ou que precisa de correção? Abra uma issue e nos ajude a manter esse site em PT-BR para ajudar pessoas como você.