Running in Parallel: Exploring Parallel Promise Execution with Promise Methods

23 / Mar / 2024 by Deepesh Agrawal 0 comments

When we have multiple promises, and we have to execute them parallelly, then we have plenty of promise methods to achieve that based on the requirement. Let’s explore those methods of Promises::

  1. Promise.all()
  2. Promise.allSettled()
  3. Promise.race()
  4. Promise.any()

Promise.all()

The Promise.all() static method takes an iterable(array) of promises as input and returns a single Promise. If all the promises are successfully fulfilled then, it will give a fulfilled promise. If any of the promise rejected, then it will reject and return the error result immediately

// Case 1: All fulfilled
const promise1 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve("Promise 1 resolved")
    }, 1000);
});

const promise2 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve("Promise 2 resolved")
    }, 2000);
});

const promise3 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve("Promise 3 resolved")
    }, 3000);
});

Promise.all([promise1, promise2, promise3]).then((values) => {
    console.log(values);
});

// output After 3 sec:

[ 'Promise 1 resolved', 'Promise 2 resolved', 'Promise 3 resolved' ]

//Case2: Any one of the promise is Rejected
If we take case1 and make the Promise2 rejected, then error result will return immediately

const promise2 = new Promise((resolve, reject) => {
    setTimeout(() => {
        reject(new Error("Promise 2 is rejected"))
    }, 2000);
});

Promise.all([promise1, promise2, promise3]).then((values) => {
    console.log(values);
}).catch((err) => {
    console.log(err)
});

We will get output after 2 sec :  Error: Promise 2 is rejectedNote: We can see, in case of Promise rejection, we are getting only the result of the rejected promises, not all the previous promises.

Promise.allSettled()

It is a static method which takes an iterable (array) of promises as input and returns a single Promise. The returned promise will wait for all promises to settle, even any of them got rejected. The result consist of an array of objects that describe the outcome of each promise. So, we get the state(fulfilled/rejected) and value of promise in object.

// Case 1: All fulfilled
const promise1 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve("Promise 1 resolved")
    }, 1000);
});

const promise2 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve("Promise 2 resolved")
    }, 2000);
});

const promise3 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve("Promise 3 resolved")
    }, 3000);
});

Promise.allSettled([promise1, promise2, promise3]).then((values) => {
    console.log(values);
}).catch((err) => {
    console.log(err)
});

// Output After 3 sec

[
{ status: 'fulfilled', value: 'Promise 1 resolved' },
{ status: 'fulfilled', value: 'Promise 2 resolved' },
{ status: 'fulfilled', value: 'Promise 3 resolved' }
]

//Case2: Any one of the promises is Rejected
If we take case1 and make the Promise2 rejected, then we will get the result of all the promises irrespective of fulfilled or rejected.

const promise2 = new Promise((resolve, reject) => {
    setTimeout(() => {
        reject(new Error("Promise 2 is rejected"))
    }, 2000);
});

Promise.allSettled([promise1, promise2, promise3]).then((values) => {
    console.log(values);
}).catch((err) => {
    console.log(err)
});

//output after 3 seconds:

[{
        status: 'fulfilled',
        value: 'Promise 1 resolved'
    },
    {
        status: 'rejected',
        reason: Error: Promise 2 is rejected
        at Timeout._onTimeout......
    },
    {
        status: 'fulfilled',
        value: 'Promise 3 resolved'
    }
]

Promise.race():

The Promise.race() static method takes an iterable(array) of promises as input and returns a single Promise.It returns the value of first settled promise, which means, like it’s a race, whoever settled first, irrespective of fulfilled or rejected, it will return the result

// Case 1
const promise1 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve("Promise 1 resolved")
    }, 1000);
});

const promise2 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve("Promise 2 resolved")
    }, 2000);
});

const promise3 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve("Promise 3 resolved")
    }, 3000);
});

Promise.race([promise1, promise2, promise3]).then((values) => {
    console.log(values);
}).catch((err) => {
    console.log(err)
});

As we can see Promise1 only needs 1 sec, so it takes less time than other promises, so it will win the race.

// Output After 1 second: Promise 1 resolved

// Case 2 : I have change Timeouts in promise1 and promise2
const promise1 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve("Promise 1 resolved")
    }, 2000);
});

const promise2 = new Promise((resolve, reject) => {
    setTimeout(() => {
        reject(new Error("Promise 2 is rejected"))
    }, 500);
});

const promise3 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve("Promise 3 resolved")
    }, 3000);
});

Promise.race([promise1, promise2, promise3]).then((values) => {
    console.log(values);
}).catch((err) => {
    console.log(err)
});

As we can see Promise2 takes only 500ms to settle, so it takes less time than all other promises, so it will win the race

Output After 500 ms: Error: Promise 2 is rejected

Promise.any():

It is a static method that takes an iterable(array) of promises as input and returns a single. The returned promise result provide the first fulfilled promise.

Note :Promise.any() looks similar to Promise.race(), but there is a difference, that Promise.any() looks for first fulfilled promise, while promise.race() does not depend on fulfillment, it will return the first settled promise, whether it’s fulfilled or rejected.

// Example
const promise1 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve("Promise 1 resolved")
    }, 2000);
});

const promise2 = new Promise((resolve, reject) => {
    setTimeout(() => {
        reject(new Error("Promise 2 is rejected"))
    }, 500);
});

const promise3 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve("Promise 3 resolved")
    }, 3000);
});

Promise.any([promise1, promise2, promise3]).then((values) => {
    console.log(values);
}).catch((err) => {
    console.log(err)
});

In this we can see that promise2 is settled within 500ms which is lesser than all promises time, but it is rejected, so, it will not be considered, next lesser time taken(2000 ms) by promise is promise1 and, it is fulfilled also, so, promise1 will be return in result.

// Output : Promise 1 resolved

Note: Now, you might be thinking what will happen if all the promises got rejected, then we get an AggregateError.

Conclusion

In this blog, we’ve explored the Promise API methods that have become essential tools in the toolkit of every JavaScript developer. From Promise.all() to Promise.any() for managing multiple promises, each method serves a distinct purpose in simplifying asynchronous programming. As you continue your journey in JavaScript development, may the power of promise methods empower you to write cleaner, more resilient code. Happy coding!

Connect with us for more such interesting updates.

FOUND THIS USEFUL? SHARE IT

Leave a Reply

Your email address will not be published. Required fields are marked *