Promise and its Different Promise Methods (Promise.all, Promise.race, etc.)

Promise and its Different Promise Methods (Promise.all, Promise.race, etc.)

#javascript #es6

Promises in Javascript

  • A promise is an object which can be returned synchronously from an asynchronous function. It will be in one of 3 possible states:
    • Fulfilled: onFulfilled() will be called (e.g., resolve() was called)
    • Rejected: onRejected() will be called (e.g., reject() was called)
    • Pending: not yet fulfilled or rejected
    • We can attach callbacks to handle (onFulfilled(), onRejected()) the fulfilled value or the reason for rejection
  • Promise Chaining - Because .then() always returns a new promise, it’s possible to chain promises with precise control over how and where errors are handled. Promises allow you to mimic normal synchronous code’s try/catch behavior. To handle error we can attach .catch() after then.
  • Creating a Promise
const doSomething = () => new Promise(resolve, reject) => {
 setTimeout(() => {
    resolve('Success');
  }, 300);

if(somethingsWrong) reject("Error");
});
  • Using a promise
doSomething()
.then(result => doSomethingElse(result))
.then(newResult => doThirdThing(newResult))
.then(finalResult => console.log(`Got the final result: ${finalResult}`))
.catch(failureCallback);

Methods

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

    • iterables - this is collection/list of promises

Promise.all

The Promise.all takes an iterable of promises as input and then returns a single promise that'll resolve into an array of the results of the input promises. However, the returned promise will reject even if a single promise from the input array rejects.

Simply, returns an array of result, if every promise resolves otherwise throws an error from the first rejected item

let pa1 = new Promise(function(resolve, reject) {
  setTimeout(function(){
    console.log('first promise');
    resolve(5);
  }, 100);
})

let pa2 = new Promise(function(resolve, reject) {
  setTimeout(function(){
    console.log('second promise');
    resolve(4);
    // reject("Failed");
  }, 100);
})

let pa3 = new Promise(function(resolve, reject) {
  setTimeout(function(){
    console.log('third promise');
    resolve(6);
  }, 100);
})

Promise.all([pa1, pa2, pa3]).then((results) => {
  const sum = results.reduce((prev, curr) => prev+curr);
  console.log(results);
  console.log(sum);
}).catch((err) => {
  console.log(err);
})
Output 
first promise
second promise
third promise
[5,4,6]
15

//if we uncomment reject() and comment resolve code part output would be: 
first promise
second promise
Failed
third promise

usecase

when all promises are expected to return the resolved state

Promise.race

The Promise.race takes an array of promises as input and returns a single promise that fulfills or rejects as soon as one of the promises in an array fulfills or rejects, with the value(resolve case) or reason(reject case) from that promise.

 let pr4 = new Promise(function (resolve, reject) {
  setTimeout(function () {
    console.log('fourth promise for the promise race');
    reject('failed');
  }, 300);
});

let pr5 = new Promise(function (resolve, reject) {
  setTimeout(function () {
    console.log('fifth promise for the promise race');
    resolve(5);
  }, 100);
});
let pr6 = new Promise(function (resolve, reject) {
  setTimeout(function () {
    console.log('sixth promise for the promise race');
    reject(6);
  }, 200);
});

Promise.race([pr4, pr5, pr6])
  .then((results) => {
    console.log(results + " Won the race");
  })
  .catch((err) => {
    console.log(err);
  });
Output 
fifth promise for the promise race
5 Won the race //first promise that resolved
'sixth promise for the promise race
fourth promise for the promise race

use case

would be to set a cutoff timer for operations and would throw error out of time.

Promise.allSettled()

The Promise.allSettled takes an iterable of promises as the input and returns a single promise that resolves after all of the given promises have either been resolved or rejected(i.e. it waits for all regardless of theri state), with an array of objects that each describes the outcome of each promise using value or reason.

let pas1 = new Promise(function (resolve, reject) {
  setTimeout(function () {
    console.log('promise one resolve in case of allSettled method');
    resolve('Failed');
  }, 100);
});

let pas2 = new Promise(function (resolve, reject) {
  setTimeout(function () {
    console.log('promise second resolve in case of allSettled method');
    resolve(20);
  }, 3000);
});

Promise.allSettled([pas1, pas2]).then((results) => {
  console.log(results);
});
Output 
You would see promise object returned with { status,value/reason }
and it would wait for 3 secs for second to get settled reagardless of first promise state.

allSettled.JPG

use case

A good use case for Promise.allSettled, would be to show our user a dialog box of which all files couldn't be send/compressed by looking over the returned data and showing their individual messages. This is a much better user experience compared to the previous one, where we only showed the first error we found.

Promise.any()

The Promise.any takes an array of promises as input and returns a single promise that resolves as soon as one of the promises in the array fulfills, with the value of the fulfilled promise.

let pan1 = new Promise(function (resolve, reject) {
  setTimeout(function () {
    console.log('promise one resolve in case of allSettled method');
    reject('Failed');
  }, 100);
});

let pan2 = new Promise(function (resolve, reject) {
  setTimeout(function () {
    console.log('promise second resolve in case of allSettled method');
    resolve(20);
  }, 500);
});

Promise.any([pan1, pan2]).then((results) => {
  console.log(results);
});
Output : 
// returns the first fulfilled value
promise one resolve in case of allSettled method
promise second resolve in case of allSettled method
20

use case

A good use case for Promise.any would be to request the same resource from multiple sources and show the first one received.

For Practice and playing out yourself here is codesandbox link for above: stackblitz.com/edit/js-4ewrsx?file=index.js