← El DOM: la web que responde

Sesión 14 · Semana 5

Promesas y async/await

Hoy · Hoja de ruta

  1. 1. Aprende: Qué es una promesa y cómo se escribe código asíncrono que se lee en orden.
  2. 2. Haz: Convierte tus simulaciones de ayer en funciones con async y await.
  3. 3. Comprueba: Tus errores asíncronos se capturan, no se pierden.

Antes de empezar · 5 minutos, sin apuntes

  1. Ayer, para hacer algo tras la carga, ¿dónde tenías que escribirlo?
  2. ¿Y para hacer tres cosas seguidas, cada una tras la anterior?
  3. ¿Qué pasa si una de ellas falla?

Una promesa es un valor futuro

Promesa

Un objeto que representa un resultado que todavía no está: puede quedar cumplida con un valor o rechazada con un error. No contiene el dato, sino el compromiso de proporcionarlo.

const promesa = new Promise((resolver, rechazar) => {
  setTimeout(() => resolver("Datos listos"), 1000);
});

promesa
  .then((valor) => console.log(valor))
  .catch((error) => console.error(error))
  .finally(() => console.log("Terminado"));

Casi nunca tendrás que crear promesas: te las darán hechas fetch y casi todas las APIs modernas. Lo que sí harás cada día es consumirlas.

async y await

async function cargarProductos() {
  try {
    const respuesta = await pedirAlServidor();
    const productos = await respuesta.json();
    return productos;
  } catch (error) {
    console.error(`No se pudieron cargar: ${error.message}`);
    return [];
  }
}

await pausa esa función hasta que la promesa se resuelva, sin bloquear el resto de la página. El código se lee de arriba abajo, como el síncrono, y los errores se capturan con el try/catch de la UD3.

Dos reglas que evitan la mayoría de tropiezos:

Regla Consecuencia
await solo dentro de async Fuera, es un error de sintaxis (salvo en el nivel superior de un módulo)
Una función async devuelve una promesa Quien la llame necesita await, o .then
const productos = cargarProductos();          // una promesa, no la lista
const productos = await cargarProductos();    // ahora sí, la lista

Ese primer caso —imprimir una promesa creyendo que son los datos— es el error número uno de esta semana. La consola muestra Promise { <pending> }, y ahí está la pista.

En serie o a la vez

// En serie: dos segundos si cada una tarda uno
const productos = await cargarProductos();
const categorias = await cargarCategorias();

// A la vez: un segundo, porque no dependen entre sí
const [productos, categorias] = await Promise.all([
  cargarProductos(),
  cargarCategorias()
]);

Espera en serie solo cuando la segunda petición necesita el resultado de la primera.

Tarea 14 · Reescribir con await

  1. Convierte tus simulaciones de la sesión 13 en funciones async.
  2. Escribe esperar(ms) que devuelva una promesa, y úsala.
  3. Encadena tres operaciones y muestra su duración total.
  4. Repite con Promise.all y compara los tiempos.
  5. Provoca un rechazo y captúralo con try/catch.
  6. Imprime a propósito la promesa sin await y explica lo que ves.
Objetivo mínimoTres funciones async con sus errores capturados.
Si lo tienesCompara medida la diferencia entre serie y paralelo.
RetoEscribe una función que reintente dos veces antes de rendirse.

Checkpoint · fin de la sesión 14

  • Explicas qué es una promesa y sus dos finales.
  • Usas async y await con try/catch.
  • Sabes que una función async devuelve una promesa.
  • Distingues cuándo esperar en serie y cuándo a la vez.
Ver respuestas

1 · Cumplida con un valor, o rechazada con un error.

2 · Una promesa pendiente: falta el await.

3 · Cuando la segunda operación necesita el resultado de la primera.