Sobes.tech
Middle

¿Qué son los generadores en Dart (sync* y async*) y cómo funcionan?

sobes.tech AI

Respuesta de la IA

Los generadores en Dart son funciones que devuelven una secuencia de valores a medida que se generan, en lugar de todo el resultado de una vez. Se utilizan las palabras clave sync* para generadores sincrónicos y async* para generadores asíncronos.

Generadores sincrónicos (sync*)

Devuelven un objeto de tipo Iterable. Utilizan la palabra clave yield para emitir el siguiente valor. El flujo de ejecución se pausa hasta que se solicita el siguiente valor (por ejemplo, en un ciclo for-in).

Iterable<int> countUpTo(int max) sync* {
  for (int i = 1; i <= max; i++) {
    yield i; // Emite un valor
  }
}

Generadores asíncronos (async*)

Devuelven un objeto de tipo Stream. Utilizan la palabra clave yield para emitir el siguiente valor. También usan yield* para emitir todos los valores de otro Stream. El flujo de ejecución se pausa y se reanuda cuando hay un nuevo evento asíncrono.

Stream<int> countUpToAsync(int max) async* {
  for (int i = 1; i <= max; i++) {
    await Future.delayed(Duration(milliseconds: 100)); // Simulación de trabajo asíncrono
    yield i; // Emite un valor
  }
}

Cómo funcionan:

Al llamar a la función generadora, el cuerpo de la función no se ejecuta inmediatamente. Se devuelve un objeto (ya sea Iterable o Stream). La ejecución real del cuerpo comienza solo cuando se intenta obtener el valor por primera vez del objeto devuelto. Cuando se alcanza la palabra clave yield, el valor se pasa "afuera" y el estado de la función se guarda. La ejecución del cuerpo se pausa. Cuando se intenta obtener el siguiente valor, la ejecución se reanuda desde donde se quedó, hasta el siguiente yield o el fin de la función.

Diferencias:

Característica sync* (Síncrono) async* (Asíncrono)
Tipo devuelto Iterable Stream
Palabras clave sync*, yield async*, yield, yield*
Uso de await No permitido Permitido
Pausa Hasta la solicitud del siguiente valor Hasta que aparezca el siguiente valor asíncrono