Node.js y APIs con Express

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 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 de estudio
18 Min

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?

Promise.all lanza las tres a la vez y espera a que todas terminen, así el tiempo total es el de la más lenta. Encadenar awaits las hace secuenciales (300ms) y quitar el await deja promesas colgadas.


Ejercicio práctico


Objetivo: optimizar y blindar código asíncrono.



  1. Escribe dos funciones fakeFetch(ms, label) que resuelvan tras un setTimeout.

  2. Llámalas primero en secuencia con dos await y mide el tiempo con console.time.

  3. Conviértelas a Promise.all y compara los tiempos.

  4. Crea el envoltorio asyncHandler y ú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.all para operaciones independientes; allSettled cuando toleras fallos parciales.
  • Un asyncHandler reenvía errores al middleware y evita try/catch repetido.
  • Toda promesa necesita un await o un .catch(); nunca la dejes flotando.
Texto Leccion 3/12
Estas viendo
Async/await: patrones seguros y errores comunes
Hablar por WhatsAppContactar por WhatsApp