Promises in JavaScript 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) which 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 any one of them gets 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 one of them gets rejected with an error.

Syntax

const promise = Promise.all([Promise1, Promise2, Promise3, ...]);
// run all promises in 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 an array of their results.

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 normal promise
wait(1500).then(result => console.log(result)); // Resolved in 1500ms

// 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 interesting thing about Promise.all() is that the output array maintains the same order as the promises are 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 second element of the output array and so on.

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

// 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), 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 any 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

Promise.all() is helpful for aggregating 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 one of them gets rejected. It is one of the best ways to perform concurrent asynchronous operations in JavaScript.

If you have any question or want to share your feedback, please feel free to send me a tweet anytime.

Happy Coding 😍

✌️ Like this article? Follow @attacomsian on Twitter. You can also follow me on LinkedIn and DEV. β˜• Buy me a coffee (cost $3)

Need help to start a new Spring Boot or MEAN stack project? I am available for contract work. Hire me to accomplish your business goals with engineering and design. Let’s talk about your project: hi@attacomsian.com.