Skip to main content

Promise.allSettled() vs Promise.all()

You guys must have used promises for better handling of asynchronous tasks in the simplest manner. 
In easy words, we can say that a Promise is an object that is representing the completion or failure of an asynchronous task

Promises were introduced to overcome the issue of callback hell. Promises make our life easier in many ways by providing enhanced readabilityeasy to maintain and of course it saves us from callback hell as well. 

Before jumping into the comparison between Promise.all() vs Promise.allSettled(), let us brush up our knowledge of promise.

What is a Promise?

promise is basically an object that may produce a single value some time in the future: either a resolved value or a reason that it’s not resolved (e.g., internet connection error). 

A promise may be in one of 3 possible states: fulfilled, rejected, or pending. Promise users can attach callbacks to handle the fulfilled value or the reason for rejection.

Three states of Promise 

Fulfilled -> When resolve() is called
Rejected -> When reject() is called.
Pending -> When a promise is not fulfilled or rejected.

A promise is settled if it’s not pending (it has been resolved or rejected). Sometimes people use resolved and settled to mean the same thing: not pending. Once settled, a promise can not be resettled. Calling resolve() or reject() again will have no effect. The immutability of a settled promise is an important feature.

Example


let geeksPromise = new Promise((resolve,reject)=>{

   // To simulate asynchronous operation we are using setTimeout(), in real life scenario you must be working with xhr request or HTML5 API
  // resolve is called whenever our asyn code is successfull
  // reject is called when it failed


   setTimeout(function(){
     resolve("success")
   });

});

  // then block is called when the promise is resolved successfully
  // catch block is called when the prromise gets rejected/ failed.

geeksPromise.then((successMessage)=>{
   console.log(`${successMessage} - Geeks Tutorial Point Rocks :)`) 
}).catch((failMessage)=>{
   console.log(`${failMessage} - Geeks Tutorial Point Rocks :)`)
});


Output







Now let us start with the real deal :)


Promise.all()

Promise.all() method is basically a promise that takes an array of Promises (an iterable) as an input and then it returns a single Promise that gets resolved when all the promises passed as an iterable/ array are resolved or when the any of the passed promises gets rejected.

Let us understand Promise.all() with the help of a real-world example. 

Suppose you are creating a chat screen. On that screen, you are showing recent chats, unread messages count, and the logged-in user detail at the top of the screen. We are provided with 2 API, One for fetching user details, and another one for a recent chat list. 

The screen must be opened when we receive data from both the API or open error screen if even one of the two API fails. In this situation, we use Promise.All().

Resolution and Rejection of Promise.all()

Resolution

1. If the passed array is empty, then a promise is returned by this method that is already resolved.


Promise.all([]).then(()=>{
   console.log("Empty Iterable gets resolved")
});

Output 
Empty Iterable gets resolved


2. When all the promises provided in the array/ iterable are resolved then this method gets resolved.


const promise1 = Promise.resolve(3);

// If the passed array contains no promise, it returns a Promise that is resolved asynchronously
const promise2 = 42;

const promise3 = new Promise((resolve, reject) => {
  resolve("Promise.all() Resolved.")
});

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

Output
//Array of fullfilled value is returned if the Promise.all() gets fulfilled
[3, 42, "Promise.all() Resolved."]



Rejection

If even one of the promises passed in the array/ iterable is rejected irrespective of whether other promises are resolved. Then this method rejects the value of that promise.



var promise1 = Promise.resolve(3);
var promise2 = 42;
var promise3 = new Promise((resolve, reject) => {
  reject("Promise Rejected Irrespective of other resolutions")
});

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


Output
Promise Rejected Irrespective of other resolutions


Promise.allSettled()

Unlike Promise.all(), Promise.allSettled() lets you know when all the promises are settled, which means either the promise is fulfilled or rejected. It returns an array of objects that describes the output of each promise whether resolved or rejected.

For each object, a status string is present. If the status is fulfilled, then we get value and when the status is rejected, then we get a reason. 
The value (or reason) reflects what value each promise was fulfilled (or rejected) with. 

var geeksResolve = Promise.resolve("Geeks Resolved");

var geeksReject = new Promise((resolve, reject) => {
  reject("Geeks Rejected")
});

var promiseArr = [geeksResolve, geeksReject];

Promise.allSettled(promiseArr).then((results) => {
  results.forEach((result) => console.log(result.status))
})

Output// Incase of resolve - Value is returned
// Incase of reject - Reason is returned


{status: "fulfilled", value: "Geeks Resolved"}
{status: "rejected", reason: "Geeks Rejected"}



Note
When an empty iterable is passed as an argument, Promise.allSettled() returns a Promise object that has already been resolved as an empty array.



Conclusion

Main thing that should be kept in mind when using Promise.all is that you can't handle partial failure. If one promise gets rejected, then the entire process is stopped and failure callback is called.

This is not ideal if the rejected promise is not doing something important and work can be done without its completion as well. 


This is when the Promise.allSettled() method comes handy, which on completion returns an array of objects with both rejected reason as well as resolved values. Unlike Promise.All() it doesn't halt when even one promise is rejected.

Promise.allSettled doesn't have a catch block to catch the rejection value whereasPromise.all has a catch block.

Comments

Popular posts from this blog

Understand Angular’s forRoot and forChild

  forRoot   /   forChild   is a pattern for singleton services that most of us know from routing. Routing is actually the main use case for it and as it is not commonly used outside of it, I wouldn’t be surprised if most Angular developers haven’t given it a second thought. However, as the official Angular documentation puts it: “Understanding how  forRoot()  works to make sure a service is a singleton will inform your development at a deeper level.” So let’s go. Providers & Injectors Angular comes with a dependency injection (DI) mechanism. When a component depends on a service, you don’t manually create an instance of the service. You  inject  the service and the dependency injection system takes care of providing an instance. import { Component, OnInit } from '@angular/core'; import { TestService } from 'src/app/services/test.service'; @Component({ selector: 'app-test', templateUrl: './test.component.html', styleUrls: ['./test.compon...

How to use Ngx-Charts in Angular ?

Charts helps us to visualize large amount of data in an easy to understand and interactive way. This helps businesses to grow more by taking important decisions from the data. For example, e-commerce can have charts or reports for product sales, with various categories like product type, year, etc. In angular, we have various charting libraries to create charts.  Ngx-charts  is one of them. Check out the list of  best angular chart libraries .  In this article, we will see data visualization with ngx-charts and how to use ngx-charts in angular application ? We will see, How to install ngx-charts in angular ? Create a vertical bar chart Create a pie chart, advanced pie chart and pie chart grid Introduction ngx-charts  is an open-source and declarative charting framework for angular2+. It is maintained by  Swimlane . It is using Angular to render and animate the SVG elements with all of its binding and speed goodness and uses d3 for the excellent math functio...

How to solve Puppeteer TimeoutError: Navigation timeout of 30000 ms exceeded

During the automation of multiple tasks on my job and personal projects, i decided to move on  Puppeteer  instead of the old school PhantomJS. One of the most usual problems with pages that contain a lot of content, because of the ads, images etc. is the load time, an exception is thrown (specifically the TimeoutError) after a page takes more than 30000ms (30 seconds) to load totally. To solve this problem, you will have 2 options, either to increase this timeout in the configuration or remove it at all. Personally, i prefer to remove the limit as i know that the pages that i work with will end up loading someday. In this article, i'll explain you briefly 2 ways to bypass this limitation. A. Globally on the tab The option that i prefer, as i browse multiple pages in the same tab, is to remove the timeout limit on the tab that i use to browse. For example, to remove the limit you should add: await page . setDefaultNavigationTimeout ( 0 ) ;  COPY SNIPPET The setDefaultNav...