JavaScript promises are one of the most popular ways of writing asynchronous functions that return a single value on completion or failure of the operation.

What is Promise.all()?

The Promise.all() is a static method (part of Promise API) that executes many promises in parallel, and waits until all of them are settled. It takes an array of promises as an input (an iterable) and returns a single promise that resolves when all of the promises in the iterable parameter get resolved, or if any of them get rejected.

For example, assume that you have several promises to download files and process the content once all are done. Now you have two choices:

  1. Run these promises one-by-one or chained them and process the data as soon as it is available.
  2. Pass all of them to Promise.all() as an array and run them simultaneously, and process the data once all promises are resolved.

The 2nd approach is better and faster! The Promise.all() itself returns a promise once all of the promises get resolved, or any of them gets rejected with an error.

Syntax

const promise = Promise.all([Promise1, Promise2, Promise3, ...])

// run all promises in the parallel
promise
	.then(result => console.log(result))
	.catch(error => console.error(`Error: ${error}`))

As you can see, it takes an array of promises (could be any iterable) and returns a new promise. The new promise resolves when all promises are settled and returns a results array.

Examples

Let us see an example of Promise.all():

// A simple promise that resolves after {ts}ms
const wait = ts => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(`Resolved in ${ts}ms`)
    }, ts)
  })
}

// Resolve as a normal promise
wait(1500).then(result => console.log(result)) // Resolved in 1500ms
wait(2000).then(result => console.log(result)) // Resolved in 2000ms
wait(3000).then(result => console.log(result)) // Resolved in 3000ms

// Promise.all
Promise.all([wait(1500), wait(2000), wait(3000)])
.then(results => console.log(results))
// ["Resolved in 1500ms", "Resolved in 2000ms", "Resolved in 3000ms"]

In the example above, the Promise.all() settles after waiting 3 seconds and returns an array of results that consists of all promises returned values.

Another thing about Promise.all() is that the output array maintains the same order as the promises specified in the iterable argument. It means the first promise resolved value will be stored in the first element of the array, the second promise will be resolved to the second element of the output array, and so on.

If the promise returned by Promise.all() rejects, it is rejected for the reason from the first promise in the input array that was rejected. Let us have an example to see what happens if any of the promises are rejected:

const wait = ts => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (ts > 2000) {
        reject(`Rejected in ${ts}ms`)
      } else {
        resolve(`Resolved in ${ts}ms`)
      }
    }, ts)
  })
}

// Promise.all
Promise.all([wait(1500), wait(2000), wait(3000)])
  .then(results => console.log(results))
  .catch(error => console.error(`Error while executing: ${error}`))
// Error while executing: Rejected in 3000ms

As you can see above, if one of the promises fails, the rest of the promises are failed too. Thus Promise.all() immediately rejects with an error.

For some operations, it may not be the desired result. You may want to execute all the promises even if some have failed. It is possible to change the default rejection behavior by handling rejection for each individual promise:

// a simple promise that resolves after {ts}ms
const wait = ts => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (ts > 2000) {
        reject(`Rejected in ${ts}ms`)
      } else {
        resolve(`Resolved in ${ts}ms`)
      }
    }, ts)
  })
}

// Promise.all
Promise.all([
  wait(1500).catch(err => err), 
  wait(2000).catch(err => err), 
  wait(3000).catch(err => err)
]).then(results => console.log(results))
// ["Resolved in 1500ms", "Resolved in 2000ms", "Rejected in 3000ms"]

Conclusion

The Promise.all() method helps aggregate many promises into a single promise and execute them in parallel. It returns a new promise which settles once all of the promises in the iterable argument are resolved or any of them gets rejected. It is one of the best ways to perform concurrent asynchronous operations in JavaScript.

✌️ Like this article? Follow me on Twitter and LinkedIn. You can also subscribe to RSS Feed.