JavaScript Promise API
Aprende la Promise API de JavaScript: Promise.all, allSettled, race, any, resolve y reject. Compara fast-fail vs allSettled con ejemplos ejecutables.
La clase Promise incluye varios métodos estáticos para combinar y crear promesas. En lugar de encadenar múltiples cadenas .then() manualmente, se pasa un array de promesas a un combinador y se obtiene una única promesa que se resuelve cuando el grupo alcanza un estado definido.
Esta página cubre los cuatro combinadores — Promise.all, Promise.allSettled, Promise.race y Promise.any — además de los dos helpers de creación Promise.resolve y Promise.reject. Si eres nuevo en las promesas, comienza primero con JavaScript: Promises.
Los ejemplos a continuación usan
.then()/.catch()para que el flujo de control sea explícito. En código real normalmente leerías el resultado conasync/await.
Elegir el combinador adecuado
| Método | Se resuelve cuando… | Se rechaza cuando… | Uso típico |
|---|---|---|---|
Promise.all | todas las promesas se cumplen | cualquier promesa se rechaza (fast-fail) | Necesitas todos los resultados y un fallo debe cancelar el conjunto |
Promise.allSettled | todas las promesas se establecen (nunca rechaza) | — | Quieres conocer cada resultado, sea éxito o fallo |
Promise.race | la primera promesa se establece (cumplir o rechazar) | la primera promesa se rechaza primero | Tiempos de espera, "el primero en responder gana" |
Promise.any | la primera promesa se cumple | todas las promesas se rechazan | Primer resultado exitoso, ignorar fallos individuales |
La distinción clave: Promise.all falla rápido — rechaza en el instante en que cualquier entrada es rechazada, incluso si otras promesas aún están pendientes. Si en cambio quieres esperar a cada promesa sin importar qué, usa Promise.allSettled.
Uso de Promise.all para tareas concurrentes
Promise.all es un método esencial para manejar múltiples promesas de forma concurrente. Cuando necesitas realizar varias operaciones asíncronas y solo continuar una vez que todas ellas se hayan completado con éxito, Promise.all es la herramienta que necesitas.
Cómo implementar Promise.all
A continuación se muestra un ejemplo que demuestra cómo usar Promise.all para manejar múltiples peticiones API simultáneamente:
En este ejemplo, Promise.all recibe un array de promesas y se resuelve con un array de sus resultados en el mismo orden que la entrada (no en el orden en que finalizaron). Si alguna promesa se rechaza, Promise.all rechaza inmediatamente con el motivo de ese primer rechazo — los resultados de las demás se descartan. Consulta Manejo de errores con promesas para saber cómo recuperarse de dichos fallos.
Dominando Promise.allSettled
A diferencia de Promise.all, el método Promise.allSettled devuelve una promesa que se resuelve después de que todas las promesas dadas se hayan cumplido o rechazado, con un array de objetos que describen el resultado de cada promesa.
Ejemplo de Promise.allSettled
Así es como puedes usar Promise.allSettled:
Nota: Promise.allSettled nunca rechaza. Siempre se resuelve con un array de objetos de resultado, cada uno con una propiedad status ('fulfilled' o 'rejected') y ya sea una propiedad value o reason.
Este método es especialmente útil cuando necesitas asegurarte de que todas las promesas lleguen a su conclusión independientemente de si se cumplen o se rechazan.
Implementando Promise.race
Promise.race es otra herramienta poderosa que permite manejar múltiples promesas resolviéndose o rechazándose tan pronto como una de las promesas del iterable se resuelve o rechaza.
Cómo usar Promise.race
A continuación se muestra una aplicación práctica de Promise.race:
Este método es ideal para escenarios donde necesitas el resultado más rápido entre múltiples operaciones asíncronas — por ejemplo, enfrentar una petición contra una promesa de tiempo de espera. Ten en cuenta que race se establece en la primera promesa en establecerse, ya sea que se cumpla o se rechace.
Obtener el primer éxito con Promise.any
Promise.any es el contrapunto optimista de Promise.race. Ignora los rechazos y se resuelve con el valor de la primera promesa en cumplirse. Solo rechaza si todas las promesas se rechazan, en cuyo caso lanza un AggregateError cuya propiedad .errors contiene todos los motivos individuales.
Cómo usar Promise.any
Usa Promise.any cuando tengas varias fuentes para los mismos datos (p. ej., servidores espejo) y solo te importe el primero que tenga éxito.
Crear promesas con resolve y reject
Promise.resolve(value) y Promise.reject(reason) son atajos para crear una promesa ya establecida sin el código repetitivo de new Promise(executor).
Promise.resolve(value)devuelve una promesa que ya está cumplida convalue. Sivaluees en sí mismo un thenable, es "adoptado" y seguido.Promise.reject(reason)devuelve una promesa que ya está rechazada conreason.
Estos helpers se usan comúnmente para devolver un valor en caché desde una función que de otro modo sería asíncrona, o para iniciar una cadena .then().
Crear un polyfill para Promise.allSettled
No todos los entornos admiten Promise.allSettled de forma nativa. Por lo tanto, implementar un polyfill puede garantizar la compatibilidad entre diferentes entornos JavaScript.
Polyfill para Promise.allSettled
Así es como puedes crear un polyfill simple:
Este polyfill proporciona una funcionalidad básica donde cada promesa se maneja individualmente y se resuelve según su resultado correspondiente, asegurando que el comportamiento de allSettled se imite de manera efectiva.
Al integrar estas técnicas avanzadas de promesas y comprender la mecánica subyacente de los polyfills, puedes llevar tu código JavaScript a nuevas cotas. Estos métodos no solo mejoran la fiabilidad del código, sino que también ofrecen un control refinado sobre las operaciones asíncronas, allanando el camino hacia aplicaciones web más robustas.