L52 - Promesas
🧠 Concepto
Section titled “🧠 Concepto”Una Promise (promesa) es un objeto que representa la finalización (o fallo) eventual de una operación asíncrona. Es una forma más estructurada y legible de manejar asincronía que los callbacks tradicionales.
Estados de una Promise
Section titled “Estados de una Promise”Una Promise tiene tres estados:
| Estado | Significado |
|---|---|
| pending | Estado inicial. La operación aún no ha terminado. |
| fulfilled | La operación se completó con éxito. → resolve(valor) |
| rejected | La operación falló. → reject(error) |
Una vez que una Promise pasa a fulfilled o rejected, su estado no puede cambiar (es inmutable).
💻 Crear una Promise
Section titled “💻 Crear una Promise”const promesa = new Promise((resolve, reject) => { // operación asíncrona setTimeout(() => { const exito = Math.random() > 0.3; if (exito) { resolve('✅ Operación exitosa'); } else { reject(new Error('❌ Algo salió mal')); } }, 1000);});resolve(valor): cambia la promesa afulfilled.reject(error): cambia la promesa arejected.
💻 Consumir una Promise
Section titled “💻 Consumir una Promise”.then() y .catch()
Section titled “.then() y .catch()”promesa .then(resultado => { console.log('Resuelta:', resultado); }) .catch(error => { console.error('Rechazada:', error.message); });.finally()
Section titled “.finally()”Se ejecuta siempre, haya éxito o error:
promesa .then(resultado => console.log(resultado)) .catch(error => console.error(error)) .finally(() => console.log('🏁 Operación terminada'));📝 Encadenamiento de Promesas
Section titled “📝 Encadenamiento de Promesas”Cada .then() devuelve una nueva Promise, lo que permite encadenar operaciones:
fetch('/api/usuario') .then(res => res.json()) .then(usuario => fetch(`/api/pedidos/${usuario.id}`)) .then(res => res.json()) .then(pedidos => { console.log('Pedidos del usuario:', pedidos); }) .catch(error => { console.error('Error en la cadena:', error); });Si cualquier .then() lanza una excepción o devuelve una Promise rechazada, el flujo salta al .catch() más cercano.
🎯 Promesas paralelas
Section titled “🎯 Promesas paralelas”Promise.all()
Section titled “Promise.all()”Ejecuta múltiples promesas en paralelo y espera a que todas se resuelvan. Si una falla, la promesa resultante se rechaza inmediatamente.
const [usuarios, productos, pedidos] = await Promise.all([ fetch('/api/usuarios').then(r => r.json()), fetch('/api/productos').then(r => r.json()), fetch('/api/pedidos').then(r => r.json()),]);console.log({ usuarios, productos, pedidos });Promise.race()
Section titled “Promise.race()”Devuelve la primera promesa que se resuelva o rechace (la más rápida):
const resultado = await Promise.race([ fetch('/api/datos'), new Promise((_, reject) => setTimeout(() => reject(new Error('Timeout')), 5000) ),]);Promise.allSettled()
Section titled “Promise.allSettled()”Espera a que todas terminen, fallen o no, y devuelve un array con los resultados:
const resultados = await Promise.allSettled([ fetch('/api/a'), fetch('/api/b'), fetch('/api/c'),]);
resultados.forEach(r => { if (r.status === 'fulfilled') { console.log('✅', r.value); } else { console.log('❌', r.reason); }});Cada objeto tiene { status: 'fulfilled' | 'rejected', value?: ..., reason?: ... }.
⚠️ Errores comunes
Section titled “⚠️ Errores comunes”- Olvidar return en el
.then(): si no retornas un valor, el siguiente.then()recibeundefined. - No capturar errores: una Promise rechazada sin
.catch()genera unUnhandledPromiseRejection. - Mezclar callbacks y promesas: usa promesas de forma consistente para evitar el callback hell.
- Confundir
Promise.all()conPromise.allSettled(): el primero falla rápido, el segundo espera a todos.
📝 Patrón: promisificar una función callback
Section titled “📝 Patrón: promisificar una función callback”function leerArchivoPromesa(ruta) { return new Promise((resolve, reject) => { fs.readFile(ruta, 'utf8', (err, data) => { if (err) reject(err); else resolve(data); }); });}🎯 Regla de oro: toda función asíncrona debería devolver una Promise. Así siempre se puede consumir con
.then()/await.