A Guide to Promise.all() in JavaScript

A Guide to Promise.all() in JavaScript

Introduction

The Promise.all() static method takes a list of promises as input and returns a single Promise. This returned promise is fulfilled when all the input promises are fulfilled (including when an empty list is passed), with an array of the fulfillment values. It is rejected when any of the input promises are rejected, with the reason for the first rejection.

When should you use it?

When your frontend requires multiple API calls that depend on each other, you need to ensure that every call is successful. In this case, you should use Promise.all().

Let's see it in action.

Case #1: All promises are fulfilled

function simulateApiCall(success, time = 0, value) { // helps simulate an api call
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            if(success) {
                resolve(value); // resolving by passing the value argument
            } else {
                reject(value); // rejecting by passing the value argument
            }
        }, time) // adding a pause of `time` ms
    });
}

const api1 = simulateApiCall(true, 1000, 'data1');
const api2 = simulateApiCall(true, 3000, 'data2');
const api3 = simulateApiCall(true, 200, 'data3');

const arrayOfPromises = [api1, api2, api3]; // creating array of promises

Promise.all(arrayOfPromises).then((response) => {
    console.log('success', response); // printing on success
}).catch((error) => {
    console.log('failed', error); // printing on error
});

// output: success [ 'data1', 'data2', 'data3' ]

In the above example, you can see that I've created a function simulateApiCall() to simulate an API call. I created 3 promises using this function and stored them in an array called arrayOfPromises. I then passed the array to the Promise.all static method to process it. After all the promises were fulfilled, a success response was printed with an array containing all the resolved promise data.

Case #2: If a promise fails, what happens next?

const api1 = simulateApiCall(true, 1000, 'data1');
const api2 = simulateApiCall(true, 3000, 'data2');
const api3 = simulateApiCall(false, 200, 'data3'); // success = false
// passing `false` to the `success` argument

const arrayOfPromises = [api1, api2, api3]; // creating array of promises

Promise.all(arrayOfPromises).then((response) => {
    console.log('success', response); // printing on success
}).catch((error) => {
    console.log('failed', error); // printing on error
});

// output: failed data3

Here, to show an error response, I've changed the third promise to be rejected (by passing false to the success argument in the simulateApiCall function). As a result, we got a failed response with the rejected value.

Case #3: Empty array is passed to the Promise.all method

const arrayOfPromises = [];

Promise.all(arrayOfPromises).then((response) => {
    console.log('success', response); // printing on success
}).catch((error) => {
    console.log('failed', error); // printing on error
});

// output: success []

As expected, we received an empty array response when we passed an empty array to the Promise.all method.

Case #4: Passing non-promise values in the array

const arrayOfPromises = [ 12, 30 ];

Promise.all(arrayOfPromises).then((response) => {
    console.log('success', response); // printing on success
}).catch((error) => {
    console.log('failed', error); // printing on error
});

// output: success [12, 30]

Here we see a special case. Even if we don't provide an array of promises, it still shows success and displays the resolved values. This will continue until we include a rejected promise. If we pass a non-promise value along with a rejected promise, it will show a rejected response.

Thanks for reading till this, visit my portfolio: rohitdasu.dev

In conclusion, we explored various scenarios using the Promise.all method. We saw how it handles an array of promises, including cases with successful and rejected promises. When an empty array is passed, it returns an empty array as expected. Additionally, we discovered that Promise.all can handle non-promise values in the array, treating them as resolved values. However, if a rejected promise is included, the entire Promise.all call will be rejected. These examples highlight the flexibility and behaviour of Promise.all in different situations, helping us understand how to use it effectively in our code.