Promise.all() Vs Promise.allSettled() in JS

Promise.all() Vs Promise.allSettled() in JS

As a developer once in a while in your javascript journey you may have got confused between the promise methods. Today in this article, I am going to walk you through promise.all() and promise.allSettled() methods of promises.

Pre-requisites

  • Familiarity with promises and it's resolve, reject methods and async js

If you are not familiar with the promise constructor please read it on MDN

Let's get started with the two promises methods and explore their differences.

1. Promise.all()

It takes an iterable(array) of promises and returns a single promise. The returned promise will resolve when all of the input's promises get resolved. This resolved promise will return an array of those resolved promises values.

Let's see this with an example.

 const promise1 = new Promise(resolve => resolve("promise1"));
 const promise2 = new Promise(resolve => resolve("promise2"));
 const promise3 = new Promise(resolve => resolve("promise3"));
 Promise.all([promise1, promise2, promise3]).then((values) =>
   console.log(values)
 );
/*As all 3 promises are being resolved promise.all() will return array of 
those resolved promises values i.e ['promise1','promise2','promise3']*/

So this was about when all the promises get resolved but what if any one of the promises gets rejected?

If any of the input‘s promises is rejected then it will be rejected immediately with the rejected promise value.

Promise.all([
         new Promise(resolve => resolve('one')),
         new Promise((resolve,reject) => reject('two')),
         new Promise(resolve => resolve('three'))
])
//Promise {<rejected>: 'two'}

Note: If any of the passed-in promises reject, Promise.all() asynchronously rejects with the value of the promise that was rejected, whether or not the other promises have been resolved.

  • If the iterable (array) contains non-promise values, they will be ignored, but still counted in the returned promise array value (if the promise is fulfilled).
//this will be counted as if the iterable passed is empty, so it gets fulfilled
var p1 = Promise.all([1,2,3]);
/* this will be counted as if the iterable passed contains only the resolved 
promise with value "4", so it gets fulfilled*/
var p2 = Promise.all([1,2,3, Promise.resolve(4)]);
/*this will be counted as if the iterable passed contains only the rejected 
promise with value "5", so it gets rejected*/
var p3 = Promise.all([1,2,3, Promise.reject(5)]);
console.log(p1);
console.log(p2);
console.log(p3);

// Promise { <fulfilled>: Array[3] }    // [1,2,3]
// Promise { <fulfilled>: Array[4] }    // [1,2,3,4]
// Promise { <rejected>: 5 }
  • If an empty iterable is passed then the promise will be resolved immediately with a returned value as an empty array.
let p = Promise.all([]);
console.log(p);
// Promise {<fulfilled>: Array(0)}     // []

2. Promise.allSettled()

It takes an iterable(array) of promises and returns a single promise that resolves after all of the given promises have either been fulfilled or rejected, with an array of objects that each describes the outcome of each promise.

The resulting object has:

  • status - shows the status of the promise
  • value - indicates the value of the fulfilled promise
  • reason - reflects the value of the rejected promise

Let's see an example with all resolved promises.

const promiseOne = new Promise(resolve => resolve("resolvedOne"));
const promiseTwo = new Promise(resolve => resolve("resolvedTwo"));
Promise.allSettled([promiseOne, promiseTwo]).then((data) =>
  console.log(data)
);
// [{status:'fulfilled',value:"resolvedOne"},{status: "fulfilled",value:"resolvedTwo"}]
  • If one of the promises gets rejected
const promiseOne = new Promise(resolve => resolve("resolvedOne"));
const promiseTwo = new Promise((resolve, reject) => reject("rejectedTwo"));
Promise.allSettled([promiseOne, promiseTwo]).then((data) =>
  console.log("promise.allSettled", data)
);
//[{status:"fulfilled",value:"resolvedOne"},{status: "rejected",reason:"rejectedTwo"}]
  • If an empty iterable is passed as an argument, Promise.allSettled() returns a Promise object that has already been resolved as an empty array.
Promise.allSettled([]).then(
  (res) => console.log( res) 
);
// []
  • If non-promise values are passed to the iterable then they will be ignored, but still counted in the returned promise value with the status as "fulfilled".
Promise.allSettled([1, 2]).then((res) =>
  console.log(res)
);
// [{status:'fulfilled',value:1},{status:'fulfilled',value:2}]

Differences

Promise.all()Promise.allSettled()
will reject as soon as one of the promises in the array rejects.will never reject, always resolves no matter if the promises of iterable are resolved or rejected.
Non-promise values will be ignored but will be present in array(resolved promise).Non-promise values will be ignored but will be present in the array.
returns array as an output containing promises values.returns array of objects as output which contains status & value/reason properties.

When to use which?

  • When you want to fetch data in parallel and if they are dependent then Promise.all() is preferred.
  • When you just want to complete all the promises irrespective of whether they are resolved or rejected then use Promise.allSettled().

That's it for this article!! hope this article was helpful and you have got a better understanding of the two promise methods now.