What is the Difference Between Promise.all and Promise.allSettled?
Nick Scialli
May 13, 2021
Promise.all
and Promise.allSettled
are two different ways to handle an array of Promises in JavaScript. Let’s compare them and talk about when it might be appropriate to use each.
How They’re Similar
The primary similarity between Promise.all
and Promise.allSettled
is that both methods take an array of Promises as an argument. You use them because you have a group of Promises that you want to handle before moving on. That’s kind of where the similarities end though. As we’ll see, the ways these methods actually handle Promises are quite different.
The Big Difference: Handling Rejection(s)
Handling rejection is the big differentiator between Promise.all
and Promise.allSettled
. If you want your group of Promise to fail immediately as soon as one of the Promises is rejected, you should use Promise.all
. However, if you want to give all Promises a shot before moving on, consider Promise.allSettled
.
Let’s take the following example of a function that returns a Promise that has a 50/50 chance of resolving or rejecting and will do so after a random amount of time.
function randomPromise(id) {
return new Promise(function (res, rej) {
setTimeout(function () {
if (Math.random() > 0.5) {
res(id);
} else {
rej(`${id} failed randomly!`);
}
}, Math.random() * 1000);
});
}
Promise.all
When handling rejection, Promise.all
is all or nothing. If one Promise rejects, Promise.all
immediately stops and calls the catch
method with the reported error.
Promise.all([randomPromise(1), randomPromise(2), randomPromise(3)])
.then(function (data) {
console.log(data);
})
.catch(function (err) {
console.error(err);
});
If all three Promises successfully resolve, you’ll see [1, 2, 3]
logged to the console. More likely, however, is that one of the Promises fails. As soon as it does you will see the error for that Promise printed to the console:
2 failed randomly!
Note a couple things:
- Even though the first and third Promise might have resolved successfully, we never make it to the
then
method, we just went straight tocatch
. - You will never see two errors in the console because
Promise.all
fails immediately when one of the Promises rejects.
Promise.allSettled
Promise.allSettled
will go ahead and let all Promise resolve or reject (i.e., settle) before giving you the results. Promise.allSettled
doesn’t reject and it gives you all the information you need in the then
method.
Let’s look at the previous example and you’ll see what I mean:
Promise.allSettled([randomPromise(1), randomPromise(2), randomPromise(3)]).then(
function (data) {
console.log(data);
}
);
If all three Promises resolve successfully, the data
logged to the console will look like this:
[
{ status: "fulfilled", value: 1 },
{ status: "fulfilled", value: 2 },
{ status: "fulfilled", value: 3 }
]
Not that we now get status
information in our then
handler. Why is that? Well, it’s because if any number of the Promises rejects, you need to know that information. With allSettled
, we can have Promises in the array reject and we’ll still wait for the rest of the Promises to resolve (or reject) before moving on to the then
handler, at which point we get information about all the Promises (even the rejected ones).
Let’s look at an example where two of the Promises rejected. Our data logged to the console might look like this:
[
{ status: "rejected", reason: "1 failed randomly!" },
{ status: "fulfilled", value: 2 },
{ status: "rejected", reason: "3 failed randomly!" }
]
Conclusion
If your Promises are related such that you’d like to immediately bail when one of the Promises rejects, Promise.all
is probably for you. However, if you’d like to keep going with the rest of the Promises even if any number of them fail, then you should probably reach for Promise.allSettled
.
Nick Scialli is a senior UI engineer at Microsoft.