Lección 3 de 12 · Lectura y práctica
Async/await: patrones seguros y errores comunes
Async/await: patrones seguros y errores comunes Las promesas y async/await son la forma moderna de escribir código asíncrono en Node. La sintaxis parece síncrona y eso la hace legible, pero esconde trampas que provocan fugas de.
Del concepto a la práctica
Taller de esta lección
Cuando dos operaciones asíncronas no dependen entre sí, Promise.all expresa la intención y evita sumar sus tiempos. Cuando una puede fallar sin invalidar las demás, Promise.allSettled conserva cada resultado.
Ejemplo resuelto
const delay = (ms, value, fail = false) => new Promise((resolve, reject) => {
setTimeout(() => fail ? reject(new Error("alerts fallo")) : resolve(value), ms);
});
const getProfile = () => delay(80, { id: "u7" });
const getAlerts = () => delay(120, ["A1"]);
const [profile, alerts] = await Promise.all([
getProfile('u7'),
getAlerts('u7')
]);Si tardan 80 y 120 milisegundos, el tiempo ideal se aproxima a 120, no a 200. Si getAlerts falla, el conjunto se rechaza; esa decisión es correcta si ambas respuestas son necesarias.
Ejecuta como módulo .mjs para permitir await al nivel superior. El rechazo de Promise.all no cancela las demás operaciones; usa cancelación cooperativa cuando esté soportada. Las duraciones80/120 son mínimos de timers ilustrativos y no un tiempo de pared exacto bajo carga. No declares 120ms como resultado garantizado ni sumes tiempos de tareas concurrentes.
Pruébalo
Sustituye las funciones por promesas con retrasos de 80 y 120 ms.
Mide el tiempo alrededor de
Promise.all.Haz fallar la segunda promesa y comprueba que el
catchrecibe el error.
Error frecuente: lanzar una promesa sin await ni manejo. Corrige retornándola, esperándola o conectándola a un controlador de errores.
Ejercicio: cambia el agregado completo a Promise.allSettled([getProfile(),delay(120,null,true)]), no únicamente la segunda operación.
Comprueba tu resultado
recibes dos estados, uno fulfilled y otro rejected, sin perder el resultado correcto de la primera.

Mapa de prácticaEl navegador envía una solicitud a la API. El servidor valida la operación y consulta los datos; después devuelve una respuesta que el navegador puede mostrar. La base de datos se comunica con el servidor y no directamente con el navegador.
Ver la infografía en tamaño completo ↗Async/await: patrones seguros y errores comunes
Las promesas y async/await son la forma moderna de escribir código asíncrono en Node. La sintaxis parece síncrona y eso la hace legible, pero esconde trampas que provocan fugas de memoria, peticiones que nunca responden y errores que se pierden en silencio. Dominar tres patrones te evita el 90% de los problemas.
1. Paralelizar cuando las operaciones son independientes
Si dos consultas no dependen una de la otra, esperarlas en secuencia desperdicia tiempo. Promise.all las lanza a la vez.
// Lento: 200ms + 150ms = 350ms
const user = await getUser(id);
const orders = await getOrders(id);
// Rápido: max(200ms, 150ms) = 200ms
const [user, orders] = await Promise.all([
getUser(id),
getOrders(id),
]);
Atención
Con Promise.all, si una promesa falla, todo el conjunto se rechaza. Cuando quieras el resultado de todas aunque alguna falle, usa Promise.allSettled y revisa el status de cada una.
2. Captura los errores en un solo lugar
En Express, en lugar de envolver cada handler en try/catch, usa un pequeño envoltorio que reenvía cualquier error al middleware de errores:
const asyncHandler = (fn) => (req, res, next) =>
Promise.resolve(fn(req, res, next)).catch(next);
app.get('/users/:id', asyncHandler(async (req, res) => {
const user = await getUser(req.params.id);
if (!user) return res.status(404).json({ error: 'no encontrado' });
res.json(user);
}));
3. No dejes promesas colgadas
Llamar a una función async sin await ni .catch() crea una promesa flotante: si falla, genera un unhandled rejection que puede tumbar el proceso. Si de verdad no quieres esperarla, captura su error explícitamente.
Tienes tres consultas independientes que tardan 100ms cada una. ¿Cómo las resuelves en ~100ms en vez de 300ms?
Ejercicio práctico
Objetivo: optimizar y blindar código asíncrono.
- Escribe dos funciones
fakeFetch(ms, label)que resuelvan tras unsetTimeout. - Llámalas primero en secuencia con dos
awaity mide el tiempo conconsole.time. - Conviértelas a
Promise.ally compara los tiempos. - Crea el envoltorio
asyncHandlery úsalo en una ruta que lance un error a propósito; comprueba que el error llega al middleware global.
Entregable: el código con ambos tiempos comentados y la captura del error manejado sin que el proceso muera.
Para recordar
Promise.allpara operaciones independientes;allSettledcuando toleras fallos parciales.- Un
asyncHandlerreenvía errores al middleware y evita try/catch repetido. - Toda promesa necesita un
awaito un.catch(); nunca la dejes flotando.
Sigue con Node.js y APIs con Express
Esta lección forma parte de un curso de Cursalo. Revisa su programa y elige entre la compra individual o el acceso a toda la escuela.
Si ya tenías acceso a este curso, entra con tu cuenta: tus derechos y tu progreso se conservan. No necesitas comprarlo de nuevo.