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);
Funcionamiento de Promise.allSettled()

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
Promise.all() VS. Promise.allSettled()

Recursos