Promise.allSettled
El método promise.allSettled()
devuelve una promesa que es resuelta después de que todas las promesas dadas hayan sido concluidas, sin importar si fueron resueltas o rechazadas. El resultado va a ser una serie de objetos describiendo el resultado de cada promesa.
const p1 = new Promise((resolve, reject) => resolve("✅"));
const p2 = new Promise((resolve, reject) => reject("❌"));
const p3 = new Promise((resolve, reject) => resolve("✅"));
Promise.allSettled([p1, p2, p3])
.then(response => console.log(response))
.catch(error => console.log(error));
/*
0: {status: "fulfilled", value: "✅"}
1: {status: "rejected", reason: "❌"}
2: {status: "fulfilled", value: "✅"}
*/
Para cada resultado hay un status
(estado). Si el estado es fulfilled
, es porque la promesa se resolvió correctamente y tenemos value
. Si el estado es rejected
, es porque la promesa se rechazó y tenemos reason
.
Sintaxis
Promise.allSettled(iterable);
Un dato curioso es que si pasamos otro tipo de dato, Promise.allSettled()
devuelve un objeto Promise
con el valor que le pasamos y status: "fulfilled"
.
const array = [
new Promise((resolve, reject) => resolve("✅")),
87,
"string",
true,
false,
null,
undefined,
[5, 23, 05],
{
name: "Fili",
age: 24
}
];
Promise.allSettled(array)
.then(response => console.log(response))
.catch(error => console.log(error));
/*
{status: "fulfilled", value: "✅"}
{status: "fulfilled", value: 87}
{status: "fulfilled", value: "string"}
{status: "fulfilled", value: true}
{status: "fulfilled", value: false}
{status: "fulfilled", value: null}
{status: "fulfilled", value: undefined}
{status: "fulfilled", value: Array(3)}
{status: "fulfilled", value: {…}}
*/
Filtrando los resultados
Con promise.allSettled
podemos filtrar datos con bastante facilidad, un ejemplo podría ser obtener las promesas que fallaron, tomando el valor de reason
.
const promises = [
new Promise((resolve, reject) => resolve("✅ Datos ...")),
new Promise((resolve, reject) => reject("❌ Problemas en el servidor")),
new Promise((resolve, reject) => reject("❌ Falló en la conexión")),
new Promise((resolve, reject) => reject("❌ Problema inesperado")),
];
Promise.allSettled(promises)
.then(results => {
const errors = results
.filter(p => p.status === "rejected")
.map(p => p.reason);
console.log(errors);
})
.catch(error => console.log(error));
// ["❌ Problemas en el servidor", "❌ Falló en la conexión", "❌ Problema inesperado"]
Async/await
Como un extra veamos el mismo ejemplo, ahora usando async/await.
const promises = [
new Promise((resolve, reject) => resolve("✅ Datos ...")),
new Promise((resolve, reject) => reject("❌ Problemas en el servidor")),
new Promise((resolve, reject) => reject("❌ Falló en la conexión")),
new Promise((resolve, reject) => reject("❌ Problema inesperado")),
];
async function getErrors(array) {
const results = await Promise.allSettled(array);
const errors = results
.filter(p => p.status === "rejected")
.map(p => p.reason);
console.log(errors);
}
getErrors(promises);
// ["❌ Problemas en el servidor", "❌ Falló en la conexión", "❌ Problema inesperado"]
Promise.all
vs. Promise.allSettled
Si te preguntas ¿Cuál es la diferencia en cuanto a Promise.all()
?, he aquí la respuesta:
Promise.all
va a ser rechazada en el momento en se rechace alguna de las promesas.Promise.allSettled
no le importa el estado de las promesas, solo esperará hasta que todas sean resueltas.
const p1 = new Promise((resolve, reject) => resolve("✅"));
const p2 = new Promise((resolve, reject) => reject("❌"));
const p3 = new Promise((resolve, reject) => resolve("✅"));
Promise.all([p1, p2, p3])
.then(response => console.log("Promesas resueltas"))
.catch(error => console.log(`Ocurrió un error: ${error}`));
// Ocurrió un error: ❌
Promise.allSettled([p1, p2, p3])
.then(response => console.log("Promesas finalizadas"))
.catch(error => console.log(`Ocurrió un error: ${error}`));
// Promesas finalizadas