Escribe código asíncrono
Aprende sobre programación asíncrona en Dart y cómo hacer solicitudes HTTP.
En este capítulo, explorarás la programación asíncrona en Dart,
lo que permitirá a tus aplicaciones realizar múltiples tareas de forma concurrente.
Aprenderás a obtener datos de internet usando el paquete http
para recuperar el resumen de un artículo de Wikipedia.
Qué lograrás
Prerrequisitos
#- Haber completado el Capítulo 2, que cubrió
la sintaxis básica de Dart y la interacción con la línea de comandos.
Deberías tener un proyecto
dartpediaconfigurado. - Familiaridad con el concepto de APIs (Application Programming Interfaces) como una forma de obtener datos.
Tareas
#En este capítulo, modificarás la aplicación de CLI
dartpedia existente para obtener y mostrar un resumen de artículo
usando
el paquete http y técnicas de programación asíncrona.
Tarea 1: Agregar la dependencia http
#Antes de que puedas realizar solicitudes HTTP,
necesitas agregar el paquete http como una
dependencia a tu proyecto.
-
Abre el archivo
dartpedia/cli/pubspec.yamldentro de tu proyecto. Este archivo se llama pubspec, y gestiona los metadatos de tu proyecto Dart, las dependencias (como el paquetehttp) y los assets. Localiza la sección
dependencies.-
Agrega
http: ^1.4.0(o la última versión estable) bajodependencies. El símbolo^permite usar versiones compatibles.yamldependencies: http: ^1.4.0 Guarda el archivo
pubspec.yaml.-
Ejecuta
dart pub geten tu terminal desde el directoriodartpedia/cli. Este comando obtiene la dependencia recién agregada y la hace disponible para su uso en tu proyecto.Deberías ver una salida similar a 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.
Tarea 2: Importar el paquete http
#Ahora que has agregado el paquete http,
necesitas importarlo en tu archivo Dart para usar sus funcionalidades.
Abre el archivo
dartpedia/bin/cli.dart.-
Agrega la siguiente sentencia
importen la parte superior del archivo, junto con el import dedart:ioexistente:dartimport 'dart:io'; import 'package:http/http.dart' as http; // Add this lineEsta línea importa el paquete
httpy le da el aliashttp. Después de hacer esto, puedes referirte a las clases y funciones dentro del paquetehttpusandohttp.(por ejemplo,http.Client,http.get). La parteas httpes una convención estándar para evitar conflictos de nombres si otra librería importada también tiene una clase o función con un nombre similar.
Tarea 3: Implementar la función getWikipediaArticle
#
Ahora crea una nueva función llamada getWikipediaArticle que
se encargue de obtener datos de una API externa.
Esta función será async porque
las solicitudes de red son operaciones asíncronas.
-
Define la firma de la función: Debajo de tu función
main(y de la funciónprintUsage), añade la siguiente firma de función.dart// ... (your existing printUsage() function) Future<String> getWikipediaArticle(String articleTitle) async { //You'll add more code here soon }Aspectos destacados del código anterior:
- El tipo de retorno
Future<String>indica que esta función eventualmente producirá un resultado de tipoString, pero no de inmediato, ya que es una operación asíncrona. - La palabra clave
asyncmarca la función como asíncrona, lo que te permite usarawaitdentro de ella.
- El tipo de retorno
-
Construye la URL de la API: Dentro de tu nueva función
getWikipediaArticle, crea un objetoUri. ElUrirepresenta el endpoint de la API de Wikipedia al que llamarás para obtener el resumen de un artículo.Añade estas líneas dentro de la función
getWikipediaArticle:dartFuture<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 ); // ... } -
Realiza la solicitud HTTP y maneja la respuesta: Ahora, usa la función de nivel superior
getdepackage:httppara realizar una solicitud HTTPGETa la URL que acabas de construir. La palabra claveawaitpausa la ejecución degetWikipediaArticlehasta que se complete la llamadagety devuelva un objetohttp.Responseobjeto.Después de que se complete la solicitud, verifica el
response.statusCodepara asegurarte de que la solicitud fue exitosa (un código de estado de200significa OK). Si tiene éxito, devuelve elresponse.body, que contiene los datos obtenidos (en este caso, JSON sin procesar). Si la solicitud falla, devuelve un mensaje de error informativo.Añade estas líneas después de la construcción del
Uridentro degetWikipediaArticle:dartFuture<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}'; }
Tarea 4: Integrar la llamada a la API en searchWikipedia
#Integrarás la llamada a la API en searchWikipedia.
Esta función albergará la lógica principal para manejar el comando wikipedia.
-
Actualiza
searchWikipediapara usarasync: Localiza tu funciónsearchWikipediay actualiza su firma aasync, ya que ahora realizará operaciones asíncronas.Tu función
searchWikipediaahora debería verse así:dart// ... (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)Aspectos destacados del código anterior:
void searchWikipedia(List<String>? arguments) async: La función ahora esasync. Esto es esencial porque llamará agetWikipediaArticle, que es una funciónasyncen sí misma y necesitará hacerawaitde su resultado.
-
Rechaza entradas
nullo cadenas de texto vacías: En este momento, si el usuario ejecutadart bin/cli.dart searchy presiona Enter sin escribir un título,stdin.readLineSync()devuelve una cadena vacía. Si el usuario presiona Control+D o Control+Z para enviar una señal de fin de archivo (EOF),stdin.readLineSync()devuelvenull, y?? ''recurre a una cadena vacía. En cualquier caso, la CLI realiza una solicitud ficticia a Wikipedia con una cadena vacía como título del artículo.Reemplaza la alternativa de seguridad
?? ''con una verificación que imprima un mensaje y finalice la función cuando no se proporcione una entrada válida.dartvoid 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")'); } -
Llama a
getWikipediaArticlee imprime el resultado: Reemplaza las dos líneasprintde marcador de posición al final desearchWikipediacon una llamada agetWikipediaArticley un únicoprintdel resultado.dartvoid 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) }Aspectos destacados del código anterior:
await getWikipediaArticle(articleTitle): Debido a quegetWikipediaArticlees una funciónasync, necesitas hacerawaitde su resultado. Esto pausa la funciónsearchWikipediahasta que elFuture<String>devuelto porgetWikipediaArticlese resuelva en unStringque contenga el contenido del artículo.print(articleContent): Imprime el resumen del artículo obtenido como una cadena JSON sin procesar en la consola.
Tarea 5: Actualizar main para llamar a searchWikipedia
#Finalmente, actualiza tu función main para
llamar a la nueva función searchWikipedia cuando
se use el comando wikipedia.
-
Localiza el bloque
else ifen tu funciónmainque actualmente maneja el comandosearch. Cambia el nombre del comando desearchawikipediay actualiza la llamada a la función.En el código de ejemplo,
mainno haceawaitde la llamada asearchWikipedia, lo que significa quemainen sí no necesita ser marcada comoasync.Tu función
mainahora debería verse así:dart// ... (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): Esto extrae todos los elementos de la listaarguments, comenzando desde el segundo elemento (índice 1). Esto elimina de manera efectiva el propio comandowikipedia, de modo quesearchWikipediasolo recibe los argumentos reales del título del artículo.searchWikipedia(inputArgs): Esto llama asearchWikipediadirectamente. Dado quemainno necesita hacer nada después de quesearchWikipediase complete, no necesitas hacerawaitde ello desdemain. Por lo tanto,mainno necesita serasync.
Tarea 6: Ejecutar la aplicación
#Ahora que has implementado la solicitud http y
la has integrado en tu aplicación, pruébala.
-
Abre tu terminal y ejecuta el siguiente comando:
bashdart run bin/cli.dart wikipedia "Dart_(programming_language)" -
Verifica para asegurarte de que la aplicación obtuvo el resumen del artículo "Dart" de la API de Wikipedia e imprimió la respuesta JSON sin procesar en la consola. Podrías 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) } -
A continuación, intenta ejecutar sin argumentos. Por ejemplo, cuando se te solicite, ingresa "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) }¡Ahora has implementado con éxito el comando básico
wikipediaque obtiene datos reales de una API externa!
Revisión
#Qué lograste
Aquí tienes un resumen de lo que construiste y aprendiste en esta lección.Dominaste futures, async y await
Aprendiste que Future representa un valor que estará disponible más tarde. La palabra clave async
keyword marca las funciones como asíncronas, y await pausa la ejecución hasta que se complete un Future.
Agregaste el paquete http como dependencia
Modificaste pubspec.yaml para agregar el paquete http, ejecutaste dart pub get
para obtenerlo, y lo importaste con un alias (as http). Puedes seguir estos pasos para agregar cualquier paquete externo desde pub.dev.
Obtuviste datos en tiempo real de Wikipedia
Construiste getWikipediaArticle() para realizar solicitudes HTTP GET utilizando la función get de
package:http, construiste URIs, verificaste códigos de estado y devolviste el cuerpo de la respuesta. ¡Tu CLI ahora obtiene datos reales de la web!
Cuestionario
#Pon a prueba tu comprensión
1 / 4awaitNo exactamente.
awaitse usa dentro de funciones asíncronas para pausar y esperar los resultados. No marca una función como asíncrona por sí misma.asynchronousNo exactamente.
Aunque es descriptiva,
asynchronousno es una palabra clave de Dart. Dart usa una palabra clave más corta para marcar funciones como asíncronas.futureNo exactamente.
Futurees un tipo que representa un valor que vendrá después, no una palabra clave para marcar funciones.async¡Correcto!
La palabra clave
asyncmarca una función como asíncrona, lo que le permite usarawaitpara esperar operaciones asíncronas.
Future<String> represent in Dart?Una cadena que se almacena en una ubicación de memoria separada.
No exactamente.
El tipo
Futureno se trata de ubicaciones de memoria o almacenamiento. Piensa en lo que significa "future" en el lenguaje cotidiano.Un valor de cadena que estará disponible en algún momento en el futuro.
¡Correcto!
Un
Futurees como una promesa. Representa un valor que aún no está disponible pero que lo estará una vez que finalice una operación asíncrona (como una solicitud de red).Una cadena que podría ser
null.No exactamente.
Las cadenas que aceptan nulos tienen un tipo
String?. UnFuture<String>representa un valor de cadena que estará disponible más tarde, después de que se complete una operación async.Una lista de cadenas que puede crecer con el tiempo.
No exactamente.
Una lista de cadenas que puede crecer sería
List<String>.Future<T>envuelve un único valor de tipoT, no una colección.
await do when placed before a Future?Convierte el
Futureen una operación síncrona.No exactamente.
La operación sigue siendo asíncrona.
awaitcambia la forma en que escribes el código, no cómo se ejecuta.Pausa la función hasta que se completa el
Future, luego devuelve el valor desempaquetado.¡Correcto!
awaitpausa la ejecución de la función hasta que se complete elFuture.Ejecuta el
Futureen un hilo separado para un mejor rendimiento.No exactamente.
Dart no usa hilos automáticamente de esta manera.
awaitfunciona dentro del modelo de bucle de eventos de hilo único de Dart.Cancela el
Futuresi tarda demasiado.No exactamente.
awaitno cancela nada ni establece tiempos de espera. Simplemente espera, independientemente de cuánto tiempo tome la operación.
await, what happens to other parts of your application?Todo se congela hasta que llega la respuesta.
No exactamente.
Si todo se congelara, async no ofrecería ningún beneficio. Piensa en por qué existe la programación asíncrona.
Dart inicia automáticamente un nuevo hilo para manejar la espera.
No exactamente.
Dart utiliza un modelo de bucle de eventos de un solo hilo.
awaitfunciona dentro de este modelo sin crear nuevos hilos.Otras operaciones asíncronas y manejadores de eventos pueden continuar ejecutándose.
¡Correcto!
Este es el beneficio clave de la programación async. Mientras espera por una operación, el bucle de eventos de Dart puede manejar otro trabajo, manteniendo tu aplicación receptiva.
El programa termina si la respuesta tarda demasiado.
No exactamente.
Los programas no terminan por esperar en operaciones async. No hay un tiempo de espera integrado que cause la terminación.
Siguiente lección
#En el próximo capítulo, te enfocarás en organizar nuestro código en librerías y paquetes reutilizables. Refactorizarás tu aplicación para mejorar su estructura y mantenibilidad creando un paquete separado para manejar los argumentos de línea de comandos.
A menos que se indique lo contrario, la documentación de este sitio refleja Dart 3.12.2. Página actualizada por última vez el 22-06-2026. Ver fuente oreportar un problema.