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

4 Ways to Communicate Across Browser Tabs in Realtime

1. Local Storage Events You might have already used LocalStorage, which is accessible across Tabs within the same application origin. But do you know that it also supports events? You can use this feature to communicate across Browser Tabs, where other Tabs will receive the event once the storage is updated. For example, let’s say in one Tab, we execute the following JavaScript code. window.localStorage.setItem("loggedIn", "true"); The other Tabs which listen to the event will receive it, as shown below. window.addEventListener('storage', (event) => { if (event.storageArea != localStorage) return; if (event.key === 'loggedIn') { // Do something with event.newValue } }); 2. Broadcast Channel API The Broadcast Channel API allows communication between Tabs, Windows, Frames, Iframes, and  Web Workers . One Tab can create and post to a channel as follows. const channel = new BroadcastChannel('app-data'); channel.postMessage(data); And oth...

Certbot SSL configuration in ubuntu

  Introduction Let’s Encrypt is a Certificate Authority (CA) that provides an easy way to obtain and install free  TLS/SSL certificates , thereby enabling encrypted HTTPS on web servers. It simplifies the process by providing a software client, Certbot, that attempts to automate most (if not all) of the required steps. Currently, the entire process of obtaining and installing a certificate is fully automated on both Apache and Nginx. In this tutorial, you will use Certbot to obtain a free SSL certificate for Apache on Ubuntu 18.04 and set up your certificate to renew automatically. This tutorial will use a separate Apache virtual host file instead of the default configuration file.  We recommend  creating new Apache virtual host files for each domain because it helps to avoid common mistakes and maintains the default files as a fallback configuration. Prerequisites To follow this tutorial, you will need: One Ubuntu 18.04 server set up by following this  initial ...

Working with Node.js streams

  Introduction Streams are one of the major features that most Node.js applications rely on, especially when handling HTTP requests, reading/writing files, and making socket communications. Streams are very predictable since we can always expect data, error, and end events when using streams. This article will teach Node developers how to use streams to efficiently handle large amounts of data. This is a typical real-world challenge faced by Node developers when they have to deal with a large data source, and it may not be feasible to process this data all at once. This article will cover the following topics: Types of streams When to adopt Node.js streams Batching Composing streams in Node.js Transforming data with transform streams Piping streams Error handling Node.js streams Types of streams The following are four main types of streams in Node.js: Readable streams: The readable stream is responsible for reading data from a source file Writable streams: The writable stream is re...