Las promesas
1. ¿Qué es una Promesa? #
En JavaScript, una promesa (Promise) es un objeto que representa la terminación o el fracaso eventual de una operación asíncrona y su valor resultante. Permite estructurar flujos asíncronos de forma lineal y legible, evitando el anidamiento excesivo de callbacks (callback hell).
Los 3 Estados de una Promesa: #
pending(Pendiente): Estado inicial; la operación no ha concluido.fulfilled(Cumplida / Resuelta): La operación concluyó con éxito (resolve(valor)), lo que ejecuta los manejadores.then().rejected(Rechazada): La operación falló (reject(error)), lo que ejecuta los manejadores.catch().
2. Consumo de Promesas con la API fetch #
La función nativa fetch() ya devuelve una promesa por sí misma, por lo que no debe envolverse en new Promise (antipatrón del constructor). Se encadena directamente con .then() y .catch():
1function obtenerPokemon(nombre) { 2 return fetch(`https://pokeapi.co/api/v2/pokemon/${nombre}`) 3 .then(response => { 4 if (!response.ok) { 5 throw new Error(`Error HTTP: ${response.status}`); 6 } 7 return response.json(); // Devuelve una nueva promesa con los datos parseados 8 }); 9} 10 11// Consumiendo la promesa 12obtenerPokemon("pikachu") 13 .then(pokemon => { 14 console.log("Nombre:", pokemon.name); 15 console.log("Altura:", pokemon.height); 16 console.log("Peso:", pokemon.weight); 17 }) 18 .catch(error => { 19 console.error("Error al obtener los datos:", error.message); 20 }) 21 .finally(() => { 22 console.log("Petición finalizada (éxito o error)"); 23 });
3. Creación de Promesas Propias con new Promise #
El constructor new Promise((resolve, reject) => ...) se reserva para transformar funciones asíncronas basadas en callbacks clásicos (como setTimeout o eventos) en promesas modernas:
1function esperar(milisegundos) { 2 return new Promise((resolve, reject) => { 3 if (milisegundos < 0) { 4 reject(new Error("El tiempo no puede ser negativo")); 5 } else { 6 setTimeout(() => resolve(`Esperado ${milisegundos}ms`), milisegundos); 7 } 8 }); 9} 10 11esperar(1000) 12 .then(mensaje => console.log(mensaje)) 13 .catch(err => console.error(err));
4. Métodos Estáticos y Combinadores de Promesas #
JavaScript ofrece métodos estáticos para coordinar múltiples operaciones asíncronas concurrentes:
| Método | Comportamiento | Cuándo usarlo |
|---|---|---|
Promise.all([p1, p2]) | Espera a que todas se cumplan. Falla inmediatamente (fail-fast) si alguna es rechazada. | Cuando todas las operaciones son obligatorias e interdependientes. |
Promise.allSettled([p1, p2]) | Espera a que todas terminen, sin importar si tuvieron éxito o fallaron, devolviendo un array con el estado (status: 'fulfilled' | 'rejected') de cada una. | Cuando quieres procesar todos los resultados sin que un fallo cancele el resto. |
Promise.any([p1, p2]) | Se resuelve con el primer éxito. Solo se rechaza si todas fallan (AggregateError). | Consultas a réplicas redundantes donde solo necesitas la primera respuesta válida. |
Promise.race([p1, p2]) | Se resuelve o rechaza con la primera que termine (sea éxito o error). | Implementar tiempos de espera (timeouts) en peticiones. |
Promise.withResolvers() (ES2024) | Devuelve { promise, resolve, reject } desestructurados para resolver promesas desde fuera sin callbacks anidados. | Patrones de cancelación, eventos desacoplados y streams. |
Ejemplo con Promise.allSettled: #
1const p1 = Promise.resolve("Datos de usuarios"); 2const p2 = Promise.reject("Fallo en el servicio de pagos"); 3 4Promise.allSettled([p1, p2]).then(resultados => { 5 resultados.forEach(res => { 6 if (res.status === "fulfilled") { 7 console.log("Éxito:", res.value); 8 } else { 9 console.log("Error:", res.reason); 10 } 11 }); 12});Salida de consola Éxito: Datos de usuarios Error: Fallo en el servicio de pagos
Resumen del tema
Conceptos clave #
- Objeto
Promise: abstracción asíncrona con 3 estados inmutables:pending,fulfilled(dispara.then()) yrejected(dispara.catch()). - Manejo Idiomático: encadenar directamente APIs basadas en promesas (
fetch()) y usar.finally()para tareas de limpieza. - Constructor
new Promise: reservado para encapsular APIs de callbacks antiguos (ej.setTimeout). - Combinadores Concurrentes:
Promise.all: todas deben triunfar (fail-fast).Promise.allSettled: espera la resolución de todas sin abortar.Promise.any: primera exitosa.Promise.race: primera en concluir.Promise.withResolvers(): creación y control directo de promesas en ES2024.
Qué debes recordar #
Encadena directamente las promesas existentes con .then(), .catch() y .finally(), y utiliza Promise.allSettled() cuando necesites coordinar múltiples peticiones concurrentes de forma tolerante a fallos.