Promise.allSettled()

Happy Thanksgiving! Let's look at Promise.allSettled() today, which was introduced as part of ES2020. Like Promise.all(), it accepts an iterable of Promises as its sole argument. Promise.allSettled() resolves after all of the Promises in its iterable have settled, i.e. either fulfilled or rejected. This method returns an array of objects that describe the outcome of each Promise provided in the iterable.

The big difference between Promise.allSettled() and Promise.all() and Promise.any() is that Promise.allSettled() does not do any of the short circuit behavior seen in the other two methods. You will recall that Promise.all() will reject immediately if any of its given Promises reject. Promise.any() will similarly resolve as soon as any of its given Promises fulfill. Promise.allSettled() on the other hand will allow all of its given Promises to settle, and then report back whether those Promises fulfilled or rejected.

As such, Promise.allSettled() is super handy if you have a bunch of different Promises you need to run, but none of those Promises are dependent on one another, so a first Promise can fulfill and a second can reject, and that's perfectly okay. Promise.allSettled() is also useful if you're debugging a group of Promises. Maybe you have four or five Promises that do depend on one another, but one of the Promises in the middle of that chain is failing and you need to figure out which one that is and why. Promise.allSettled() will give you a view into how each Promise behaves and what it returns or rejects with.

Syntax

Promise.allSettled(iterable);

Parameters

  • iterable - An iterable object such as an Array.

Return Value

Promise.allSettled() returns a pending Promise that resolves asynchronously once every Promise in the provided iterable settles, regardless of whether each Promise fulfills or rejects. When this happens, an array containing outcome objects is passed to the the returned Promise's handler function.

Each outcome object will contain a few things: a status property, which will be a string. This status property will either be the value "fulfilled" or the value "rejected". If the status is fulfilled, then the outcome object will also contain a value property, which is the value that that particular Promise resolved with. If the status is rejected, then the outcome object will instead contain a reason property, which is the reason that that particular Promise rejected with.

const promise1 = Promise.resolve("first promise done");
const promise2 = "second item done"; // not a Promise!
const promise3 = new Promise((resolve, reject) => {
  setTimeout(() => resolve("third promise done"), 2000);
});
const promise4 = Promise.reject("error!!!");

Promise.allSettled([promise1, promise2, promise3, promise4]).then((values) => {
  console.log(values);
});
/*
 expected result (after two seconds):
 [
  { status: 'fulfilled', value: 'first promise done' },
  { status: 'fulfilled', value: 'second item done' },
  { status: 'fulfilled', value: 'third promise done' },
  { status: 'rejected', reason: 'error!!!' }
 ]
 */

However, in the event that an empty iterable is passed to Promise.allSettled(), then this method returns a Promise that is already resolved as an empty array.

Promise.allSettled([]).then((results) => {
  console.log(results);
});
// expected result: []

From MDN: The Promise.allSettled() method returns a Promise that resolves after all of the given Promises have either fulfilled or rejected, with an array of objects that each describes the outcome of each Promise.

See more examples and further documentation here.