Saltar al contenido principal

Programación asincrónica

Información sobre cómo escribir código asíncrono en Dart.

Las librerías de Dart están llenas de funciones que devuelven objetos Future o Stream. Estas funciones son asíncronas: retornan después de configurar una operación que posiblemente consuma mucho tiempo (como la E/S), sin esperar a que esa operación se complete.

Las palabras clave async y await admiten la programación asíncrona, permitiéndote escribir código asíncrono que se parece al código síncrono.

Manejo de Futures

#

Cuando necesitas el resultado de un Future completado, tienes dos opciones:

El código que utiliza async y await es asíncrono, pero se parece mucho al código síncrono. Por ejemplo, aquí tienes un fragmento de código que utiliza await para esperar el resultado de una función asíncrona:

dart
await lookUpVersion();

Para usar await, el código debe estar en una función async, una función marcada como async:

dart
Future<void> checkVersion() async {
  var version = await lookUpVersion();
  // Do something with version
}

Usa try, catch y finally para manejar errores y realizar limpieza en el código que utiliza await:

dart
try {
  version = await lookUpVersion();
} catch (e) {
  // React to inability to look up the version
}

Puedes usar await varias veces en una función async. Por ejemplo, el siguiente código espera tres veces los resultados de las funciones:

dart
var entrypoint = await findEntryPoint();
var exitCode = await runExecutable(entrypoint, args);
await flushThenExit(exitCode);

En await expression, el valor de expression suele ser un Future; si no lo es, el valor se envuelve automáticamente en un Future. Este objeto Future indica una promesa de devolver un objeto. El valor de await expression es ese objeto devuelto. La expresión await hace que la ejecución se pause hasta que ese objeto esté disponible.

Si obtienes un error en tiempo de compilación al usar await, asegúrate de que await esté en una función async. Por ejemplo, para usar await en la función main() de tu aplicación, el cuerpo de main() debe estar marcado como async:

dart
void main() async {
  checkVersion();
  print('In main: version is ${await lookUpVersion()}');
}

Para una introducción interactiva al uso de futures, async y await, consulta el tutorial de programación asíncrona.

Declaración de funciones async

#

Una función async es una función cuyo cuerpo está marcado con el modificador async.

Agregar la palabra clave async a una función hace que devuelva un Future. Por ejemplo, considera esta función síncrona, que devuelve un String:

dart
String lookUpVersion() => '1.0.0';

Si la cambias para que sea una función async (por ejemplo, porque una implementación futura consumirá tiempo), el valor devuelto es un Future:

dart
Future<String> lookUpVersion() async => '1.0.0';

Ten en cuenta que el cuerpo de la función no necesita usar la API de Future. Dart crea el objeto Future si es necesario. Si tu función no devuelve un valor útil, haz que su tipo de retorno sea Future<void>.

Para una introducción interactiva al uso de futures, async y await, consulta el tutorial de programación asíncrona.

Manejo de Streams

#

Cuando necesites obtener valores de un Stream, tienes dos opciones:

Un bucle for asíncrono tiene la siguiente forma:

dart
await for (varOrType identifier in expression) {
  // Executes each time the stream emits a value.
}

El valor de expression debe tener el tipo Stream. La ejecución procede de la siguiente manera:

  1. Espera hasta que el stream emita un valor.
  2. Ejecutar el cuerpo del bucle for, con la variable establecida en ese valor emitido.
  3. Repite 1 y 2 hasta que el stream se cierre.

Para dejar de escuchar el stream, puedes usar una sentencia break o return, la cual sale del bucle for y cancela la suscripción al stream.

Si obtienes un error en tiempo de compilación al implementar un bucle for asíncrono, asegúrate de que el await for esté en una función async. Por ejemplo, para usar un bucle for asíncrono en la función main() de tu aplicación, el cuerpo de main() debe estar marcado como async:

dart
void main() async {
  // ...
  await for (final request in requestServer) {
    handleRequest(request);
  }
  // ...
}

Para obtener más información sobre el soporte de programación asíncrona de Dart, consulta la documentación de la librería dart:async.