Difference Between Promise.all and Promise.allSettled
Promise.all
and Promise.allSettled
act differently. Let's explore this beautiful variety:
Test Harness
Let's set up a little test to see what the differences are. This test has some Promises that fail (and reject) and some Promises that win (and resolve).
Where it's set up now to Promise.all
, in later experiments, we'll change it to Promise.allSettled
.
function fail(ms = 1000) {
return new Promise((_resolve, reject) => {
setTimeout(() => {
console.log("Failing now");
reject("Failed");
}, ms);
});
}
function win(ms = 1000) {
return new Promise((resolve) => {
setTimeout(() => {
console.log("Winning now");
resolve("Won");
}, ms);
});
}
(async function main() {
try {
// prettier-ignore
const thing = await Promise.all([
win(1000),
fail(2000),
win(3000)
]);
console.log("resolved with", thing);
} catch (err) {
console.log("rejected with", err);
}
})();
How Promise.all Acts
When we run the test with Promise.all
, we get this output:
❯ node test.js
I'm going to win
I'm going to fail
I'm going to win
Winning now
Failing now
rejected with Failed
Winning now
Things to notice:
- It rejects on the first failure.
- Async operations (the
setTimeout
callbacks) still run (eg, 2nd 'Winning now'). - It doesn't wait for all promises to resolve.
- When Promise rejects, the Promise is caught.
If we change the experiment a bit to remove the failure:
const thing = await Promise.all([
win(1000),
win(3000)
]);
The output is:
❯ node test.js
Winning now
Winning now
resolved with [ 'Won', 'Won' ]
Notice:
- With no failures, all resolved values come back in one array.
How Promise.allSettled Acts
If we change the experiment to use Promise.allSettled
:
const thing = await Promise.allSettled([
win(1000),
fail(2000),
win(3000)
]);
And then run, we get:
❯ node test.js
Winning now
Failing now
Winning now
resolved with [
{ status: 'fulfilled', value: 'Won' },
{ status: 'rejected', reason: 'Failed' },
{ status: 'fulfilled', value: 'Won' }
]
What it did:
- It always resolves, even when one of the Promises rejects.
- It guarantees resolution of all Promises before it, itself resolves.
- An array is returned that contains objects with the status of each promise resolution, be it resolved or rejected.
When to Use
Use Promise.all
when:
You want quick returns, knowing when any of the Promises have failed. The rest will run, but you'll know as soon as you can about the first problem.
Use Promise.allSettled
when:
You want to know the resolution value of each and every Promise, whether failed or successful, and you're willing to wait however long that takes.
It seems to me that Promise.allSettled
usage is more-commonly useful, but I tend to see more Promise.all
in code in practice.