JS Promises

JavaScript Promises are a modern approach to handle asynchronous operations. Although we can handle small small asynchronous operations using Callback Functions, but not large operations. Promises can handle long and nested asynchronous operations easily.

Promises are also helpful to handle long chaining of nested callback functions known as callback hell in javascript.

Build-in Promise in JavaScript

  1. Fetch API
  2. getBattery

Callback Hell

To perform asynchronous operations, we need to used timer functions. This can leads to a long chain of function with parameter functions, also known as callback hell. Promises are the solution for callback hell in javascript. See example below

app running

done after timer


var myFunc=function(){
    return setTimeout(function(){
            console.log('done after timer');  // second
    });
};
myFunc();
console.log('app running'); // first

Promise States

A Promise is always in one of these states, pending, fulfilled and rejected. For chaining in Promise, we can use then or catch method.

javascript promise
Javascript Promise
Promise State Explanation
pending The initial state, waiting for fulfill or reject
fulfilled the operation has successfully done
rejected the operation was failed

A Promise is said to be resolved or settled when it is fulfilled or rejected. Once settled (resolved or rejected), a Promise cannot be changed. That means a Promise is immutable after settled.

The then(), catch() and finally methods of Promise are used to handle callbacks that executes when it is settled or resolved.

Promise.then

Promise.then method is used to call callback function when promise is resolved. Then can have one or two parameters.

done


   
    function done(){
       console.log("done");
    }
    function error(){
       console.error("error");
    }
   
    var promise=new Promise((resolve,reject)=>{
        resolve();
        reject();
    });
    
    promise.then(done).catch(error);

Promise.catch

Promise.catch method is used to call callback function if promise is rejected.

error found


   
    function done(){
       console.log(age);
       let age;
    }
    function error(){
        throw new Error("error found")
    }
   
    var promise=new Promise((resolve,reject)=>{
        resolve();
        reject();
    });
    
    promise.then(done).catch(error);

In the above example, done and error are two callback functions. promise is a new instance of Promise Object with callback. There are two parameters of callback, resolve and reject.

As let is defined later and used earlier, this will throw error. But promise can handle this asynchronous. You can check error in browser console.


Promise.resolve

Promise.resolve method resolve a value given to Promise. If the value is Promise, then the promise is returned.

Promise {<fulfilled>: 1}


    let x=Promise.resolve(1);
    console.log(x);

3

hello


let x=Promise.resolve('hello');
x.then(i=>console.log(i));

let y=3;
console.log(y);

Promise.reject

Promise.reject method reject a value given to Promise. If the value is Promise, then the promise is returned.

Promise {<rejected>: 1}


    let x=Promise.reject(1);
    console.log(x);


Promise.all

Promise.all method takes an array of promises (Array with Promise element) and return an array with resolved values. If any Promise rejects, it will return rejected reason.

[1,2,3]


    let x=Promise.resolve(1);
    let y=Promise.resolve(2);
    let z=Promise.resolve(3);

    let arr=[x,y,z];

    Promise.all(arr).then(i=>{console.log(i)});

Promise.allSettled

Promise.allSettled method use any array of promises as argument and returns a single promise. The return promise fulfills when all promises in array are settled.

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


    const x=Promise.resolve(1);
    const y=Promise.resolve(2);
    const z=Promise.resolve(3);

    const p=[x,y,z];

    Promise.allSettled(p).then(i=>console.log(i));

Promise.allSettled with reject

[{status: 'fulfilled', value: 1}, {status: '"rejected"', reason: 2}, {status: 'rejected', reason: 3}]


    const x=Promise.resolve(1);
    const y=Promise.resolve(2);
    const z=Promise.reject(3);
    
    const p=[x,y,z];
    
    Promise.allSettled(p).then(i=>console.log(i));

Iterate over Promise.allSettled

{status: 'fulfilled', value: 1}

{status: 'fulfilled', value: 2}

{status: 'fulfilled', value: 3}]


    const x=Promise.resolve(1);
    const y=Promise.resolve(2);
    const z=Promise.resolve(3);
        
    const p=[x,y,z];
        
    Promise.allSettled(p).then(i=>{
        for( let j of i ){
            console.log(j);
        }
    });

Promise.any

Promise.any method takes an array of promises (Array with Promise element) and return single promise. The returned value is the first resolved promise.

1


    let x=Promise.resolve(1);
    let y=Promise.resolve(2);
    let z=Promise.resolve(3);

    let arr=[x,y,z];

    Promise.any(arr).then(i=>{console.log(i)});

2


        let x=Promise.reject(1);
        let y=Promise.resolve(2);
        let z=Promise.resolve(3);
    
        let arr=[x,y,z];
    
        Promise.any(arr).then(i=>{console.log(i)});
    

Promise.race

Promise.race takes an array of promises and resolve the first completed promise asynchronously. That's why its called race.


const p1 = new Promise((resolve, reject) => {
    setTimeout(resolve, 500, 'promise 1');
});
      
const p2 = new Promise((resolve, reject) => {
    setTimeout(resolve, 300, 'promise 2');
});
      
Promise.race([p1, p2]).then((value) => {
    console.log(value);
});