Volver a JavaScript Básico

Promesas y Async/Await

JavaScript es de un solo hilo. Las promesas y async/await permiten manejar operaciones asíncronas de forma limpia.

Callbacks (la forma antigua)

// Callback hell — difícil de leer y mantener obtenerUsuario(id, (err, usuario) => { if (err) return manejarError(err); obtenerPosts(usuario.id, (err, posts) => { if (err) return manejarError(err); renderizarPosts(posts); }); });

Promesas

// Crear una promesa const esperar = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); // Consumir una promesa fetch("https://api.ejemplo.com/usuarios") .then(response => response.json()) .then(datos => console.log(datos)) .catch(error => console.error(error)) .finally(() => console.log("Terminado"));

Async / Await

async function obtenerUsuario(id) { try { const response = await fetch(`/api/usuarios/${id}`); if (!response.ok) throw new Error(`HTTP ${response.status}`); const usuario = await response.json(); return usuario; } catch (error) { console.error("Error al obtener usuario:", error); throw error; // Relanzar para que el llamador lo maneje } }

Ejecución en Paralelo

// Secuencial (lento) — cada uno espera al anterior const usuario = await obtenerUsuario(1); // 200ms const posts = await obtenerPosts(1); // 200ms // Total: ~400ms // Paralelo (rápido) — todos inician al mismo tiempo const [usuario, posts] = await Promise.all([ obtenerUsuario(1), obtenerPosts(1), ]); // Total: ~200ms

Combinadores de Promesas

// Promise.all — esperar TODOS; falla si alguno falla const resultados = await Promise.all([p1, p2, p3]); // Promise.allSettled — esperar TODOS; nunca falla const liquidadas = await Promise.allSettled([p1, p2, p3]); liquidadas.forEach(({ status, value, reason }) => { if (status === "fulfilled") console.log(value); else console.error(reason); }); // Promise.race — el primero en resolver gana const primero = await Promise.race([lento, rapido, medio]); // Promise.any — el primero en TENER ÉXITO gana (ES2021) const exitoso = await Promise.any([p1, p2, p3]);

Iteración Asíncrona

async function* paginar(urlBase) { let pagina = 1; while (true) { const datos = await fetch(`${urlBase}?pagina=${pagina}`).then(r => r.json()); if (datos.length === 0) return; yield datos; pagina++; } } for await (const pagina of paginar("/api/posts")) { console.log(pagina); }

Regla de oro: Siempre maneja los rechazos de promesas — ya sea con .catch() o un bloque try/catch dentro de una función async.