¿Cuál es la diferencia entre async y async * en Dart?

84

Estoy haciendo una aplicación usando el framework flutter. Durante esto me encontré con las palabras clave en Dart asyncy async*. ¿Alguien puede decirme cuál es la diferencia entre ellos?

Jagraj Singh
fuente

Respuestas:

112

Marcar una función como asynco le async*permite usar async/ awaitpalabra clave para usar un Future.

La diferencia entre ambos es que async*siempre devolverá ay Streamofrecerá algo de azúcar sintáctico para emitir un valor a través de la yieldpalabra clave.

Por tanto, podemos hacer lo siguiente:

Stream<int> foo() async* {
  for (int i = 0; i < 42; i++) {
    await Future.delayed(const Duration(seconds: 1));
    yield i;
  }
}

Esta función emite un valor cada segundo, que se incrementa cada vez

Rémi Rousselet
fuente
2
Debe agregar dónde obtiene el ejemplo, es bueno leerlo Dart Documentationy también una referencia :)
Skizo-ozᴉʞS
3
@ Skizo-ozᴉʞS el enlace está muerto. El mejor documento que pude encontrar es: dart.dev/tutorials/language/streams .
wdev
1
Al marcar una función como asíncrona *, podemos usar la palabra clave yield y devolver un flujo de datos.
Yash
71

Respuesta corta

  • async te da un Future
  • async*te da un Stream.

asincrónico

Agrega la asyncpalabra clave a una función que realiza un trabajo que puede llevar mucho tiempo. Devuelve el resultado envuelto en un Future.

Future<int> doSomeLongTask() async {
  await Future.delayed(const Duration(seconds: 1));
  return 42;
}

Puede obtener ese resultado esperando el futuro:

main() async {
  int result = await doSomeLongTask();
  print(result); // prints '42' after waiting 1 second
}

asincrónico *

Agrega la async*palabra clave para crear una función que devuelva un montón de valores futuros uno a la vez. Los resultados se envuelven en una secuencia.

Stream<int> countForOneMinute() async* {
  for (int i = 1; i <= 60; i++) {
    await Future.delayed(const Duration(seconds: 1));
    yield i;
  }
}

El término técnico para esto es función de generador asíncrono . Usas yieldpara devolver un valor en lugar de returnporque no estás abandonando la función.

Puede utilizar await forpara esperar cada valor emitido por la secuencia.

main() async {
  await for (int i in countForOneMinute()) {
    print(i); // prints 1 to 60, one integer per second
  }
}

Continuando

Mire estos videos para obtener más información, especialmente el de Generadores:

Suragch
fuente
2
'Mira estos videos': sería genial si también pudieras proporcionar referencias textuales . No todo el mundo es aficionado a los videos ...
Aconcagua