How to wait for 2 or more promises to resolve in JavaScript
By Flavio Copes
Learn how to wait for two or more promises to resolve in JavaScript with Promise.all(), reading the results from the returned array, using await or then().
The answer is Promise.all(). You pass it an array of promises, and it gives you back a single promise that resolves when all of them have resolved.
Say you need to fire up 2 or more promises and wait for their result. And you want to go on, once you have both resolved.
Here’s how you do it in JavaScript:
const promise1 = //...
const promise2 = //...
const data = await Promise.all([promise1, promise2])
const dataFromPromise1 = data[0]
const dataFromPromise2 = data[1]
The results come back in the same order as the promises in the array. It doesn’t matter which one finishes first.
Since data is an array, you can use destructuring to make this shorter:
const [user, repos] = await Promise.all([
fetch('https://api.github.com/users/flaviocopes'),
fetch('https://api.github.com/users/flaviocopes/repos')
])
Why not just await each promise?
You could write this:
const user = await fetch('https://api.github.com/users/flaviocopes')
const repos = await fetch('https://api.github.com/users/flaviocopes/repos')
It works, but it’s slower. The second request only starts after the first one has finished.
With Promise.all() both requests run at the same time. If each one takes a second, you wait one second instead of two. The two requests don’t depend on each other, so there’s no reason to run them in sequence.
What happens if one promise rejects?
Promise.all() fails fast. As soon as one promise rejects, the whole thing rejects with that error. You don’t get the results of the promises that succeeded.
Wrap the call in a try/catch block to handle the failure:
try {
const [user, repos] = await Promise.all([promise1, promise2])
} catch (err) {
console.error(err)
}
If you want the outcome of every promise, even when some fail, use Promise.allSettled() instead. It always resolves, and each result tells you if that promise was fulfilled or rejected.
You can see how Promise.all() compares to allSettled(), race() and any() in the promise combinators tool.
If you prefer using pure promises and not async/await, use this syntax:
const promise1 = //...
const promise2 = //...
Promise.all([promise1, promise2]).then(data => {
const dataFromPromise1 = data[0]
const dataFromPromise2 = data[1]
})
One thing to remember: await only works inside an async function, or at the top level of an ES module. If you get a syntax error on the await line, that’s the reason.
Related posts about js: