← Flutter & Dart

Dart avanzado

¿Qué es un `Future` en Dart y cómo funcionan `async` y `await`?

Ver respuesta — intenta responderla en voz alta primero

Un Future representa un valor que estará disponible más adelante (una operación asíncrona, como una petición de red). async marca una función como asíncrona y hace que devuelva un Future. await pausa la ejecución de esa función hasta que el Future se resuelva, sin bloquear el hilo principal.

Dart corre en un solo hilo. Para no congelar la interfaz mientras espera algo lento (red, disco), usa asincronía basada en un event loop.

  • Future<T>: una promesa de un valor de tipo T que llegará después. Puede completarse con un valor o con un error.
  • async: marca la función. Automáticamente devuelve un Future.
  • await: dentro de una función async, espera a que un Future termine y "desenvuelve" su valor. Mientras espera, Dart sigue atendiendo otras cosas.

Alternativa sin await: .then() para encadenar y .catchError() para errores. Con async/await el código se lee como si fuera síncrono, lo que suele ser más claro.

// Simula pedir datos que tardan
Future<String> obtenerUsuario() async {
  await Future.delayed(Duration(seconds: 1)); // simula la espera
  return "Mike";
}

Future<void> main() async {
  print("Pidiendo usuario...");

  // Con async/await
  final usuario = await obtenerUsuario();
  print("Hola, $usuario");

  // Manejo de errores con try/catch
  try {
    final dato = await Future<int>.error("algo falló");
    print(dato);
  } catch (e) {
    print("Error atrapado: $e");
  }

  // Versión con .then() (mismo resultado, otra sintaxis)
  obtenerUsuario().then((u) => print("Con then: $u"));
}

Salida aproximada:

Pidiendo usuario...
Hola, Mike
Error atrapado: algo falló
Con then: Mike

Olvidar el await y trabajar con el Future en vez de con su valor. Si escribes final usuario = obtenerUsuario(); (sin await), usuario es un Future<String>, no el String. Al imprimirlo verás algo como Instance of 'Future<String>'. Otro error: usar await fuera de una función async (no compila).

"Un Future es un valor que estará disponible más adelante, típico de operaciones lentas como una llamada de red. Como Dart es de un solo hilo, uso asincronía para no congelar la UI. Marco la función con async para que devuelva un Future, y uso await para esperar su resultado sin bloquear el hilo; mientras espera, el event loop atiende otras tareas. Los errores los manejo con try/catch. La alternativa es .then(), pero async/await hace que el código se lea como síncrono."

Reto rápido

¿Qué imprime este código y por qué?

Future<void> main() async {
  print("A");
  Future(() => print("B"));
  await Future.delayed(Duration.zero, () => print("C"));
  print("D");
}
Ver respuesta

Imprime A, C, B, D... casi. En realidad el orden típico es A, luego se agendan B y C en la cola de eventos. Como ambos son Future normales van a la event queue en el orden en que se agendaron: primero B, después C. Pero await en main pausa hasta que su Future termine. Resultado usual: A, B, C, D. La clave a explicar: print("A") es síncrono y sale primero; el resto son tareas asíncronas que corren cuando el hilo principal queda libre, respetando el orden de la cola.