Dart: Future, async/await y Streams

Cómo se ordena realmente la ejecución, y cómo escuchar varios valores en el tiempo

⏳ 1. Future y async/await

Orden real de los print():

1. Inicio
2. Empieza a pedir datos...
3. Fin de main
4. Datos recibidos

Cambia cómo se llama a obtenerDatos()

void main() {
  print('1. Inicio');
  obtenerDatos();             // <- NO se espera, sigue de inmediato  print('3. Fin de main');
}
Future obtenerDatos() async {
  print('2. Empieza a pedir datos...');
  await Future.delayed(Duration(seconds: 2));
  print('4. Datos recibidos');
}
💡 Lo importante: await solo pausa esa función

Si main() no espera el Future con await, sigue ejecutando sus propias líneas mientras obtenerDatos() trabaja en segundo plano. Por eso, sin await en main, "Fin de main" sale ANTES que "Datos recibidos".

🌊 2. Streams (varios valores en el tiempo)

Stream Registro de eventos del:

Evento 1: emite 3 → descartado por where()
Evento 2: emite 7 → pasa el filtro, listener imprime 7
Evento 3: emite 1 → descartado por where()
Evento 4: emite 9 → pasa el filtro, listener imprime 9
Evento 5: emite 4 → descartado por where()
Evento 6: emite 12 → pasa el filtro, listener imprime 12

Prueba tus propias emisiones

final stream = Stream.fromIterable([3, 7, 1, 9, 4, 12]);

stream
    .where((valor) => valor >= 5)
    .listen((valor) => print('Recibido: $valor'));
💡 Future vs Stream

Un Future representa un único valor que llegará en el futuro (o un error). Un Stream representa una secuencia de valores que van llegando con el tiempo — perfecto para eventos de teclado, mensajes de un socket, o resultados que llegan poco a poco.

🎯 Conceptos Clave

Future

  • Representa un valor futuro (o error)
  • await pausa hasta tenerlo

async / await

  • Solo pausa la función marcada async
  • El resto del programa sigue

Stream

  • Múltiples valores en el tiempo
  • .listen(), .where(), async*/yield

💪 Ejercicio Práctico

Practica async/await y Streams

  1. Escribe una función Future<int> sumarAsync(int a, int b) async que devuelva a + b tras un Future.delayed.
  2. Envuelve la llamada a un Future en try/catch para capturar un posible error.
  3. Crea un generador de stream con Stream<int> contarHasta(int n) async* { ... yield i; ... }.

Solución 1

Future sumarAsync(int a, int b) async {
  await Future.delayed(Duration(seconds: 1));
  return a + b;
}

Solución 2

try {
  final resultado = await sumarAsync(2, 3);
  print(resultado);
} catch (e) {
  print('Error: $e');
}

Solución 3

Stream contarHasta(int n) async* {
  for (int i = 1; i <= n; i++) {
    await Future.delayed(Duration(milliseconds: 500));
    yield i;
  }
}