Understanding JavaScript Promises: A Comprehensive Guide

Understanding JavaScript Promises: A Comprehensive Guide

Day 29 of 60 : Learn Full Stack Web Development with JavaScript Promise.

  • Promises in real-life express a trust between two or more persons and an assurance that a particular thing will surely happen.

  • In javascript, a Promise is an object which ensures to produce a single value in the future (when required).

  • Promise in javascript is used for managing and tackling asynchronous operations.

Need for JavaScript Promise :

  • Till now, we learned about events and callback functions for handling the data. But, its scope is limited.

  • It is because events were not able to manage and operate asynchronous operations.

  • Thus, Promise is the simplest and better approach for handling asynchronous operations efficiently.

There are two possible differences between Promise and Event Handlers:

  1. A Promise can never fail or succeed twice or more. This can happen only once.

  2. A Promise can neither switch from success to failure, or failure to success. If a Promise has either succeeded or failed, and after sometime, if any success/failure callback is added, the correct callback will be invoked, no matter the event happened earlier.

Terminology of Promise

A promise can be present in one of the following states:

  1. pending: The pending promise is neither rejected nor fulfilled yet.

  2. fulfilled: The related promise action is fulfilled successfully.

  3. rejected: The related promise action is failed to be fulfilled.

  4. settled: Either the action is fulfilled or rejected.

Promises of Promise

A JavaScript Promise promises that:

  1. Unless the current execution of the js event loop is not completed (success or failure), callbacks will never be called before it.

  2. Even if the callbacks with then() are present, but they will be called only after the execution of the asynchronous operations completely.

  3. When multiple callbacks can be included by invoking then() many times, each of them will be executed in a chain, i.e., one after the other, following the sequence in which they were inserted.

Methods in Promise

The functions of Promise are executable almost on every trending web browsers such as Chrome, Mozilla, Opera, etc. The methods list is:

Method NameSummary
Promise.resolve(promise)This method returns promise only if promise.constructor==Promise.
Promise.resolve(thenable)Makes a new promise from thenable containing then().
Promise.resolve(obj)Makes a promise resolved for an object.
Promise.reject(obj)Makes a promise rejection for the object.
Promise.all(array)Makes a promise resolved when each item in an array is fulfilled or rejects when items in the array are not fulfilled.
Promise.race(array)If any item in the array is fulfilled as soon, it resolves the promise, or if any item is rejected as soon, it rejects the promise.

Constructor in Promise

new Promise(function(resolve, reject){});

Here, resolve(thenable) denotes that the promise will be resolved with then().
Resolve(obj) denotes promise will be fulfilled with the object
Reject(obj) denotes promise rejected with the object.

Create a Promise

To create a promise object, we use the Promise() constructor.

let promise = new Promise(function(resolve, reject){
     //do something
});
  • The Promise() constructor takes a function as an argument. The function also accepts two functions resolve() and reject().

  • If the promise returns successfully, the resolve() function is called. And, if an error occurs, the reject() function is called.

Let's suppose that the program below is an asynchronous program. Then the program can be handled by using a promise.

Example 1: Program with a Promise

const count = true;

let countValue = new Promise(function (resolve, reject) {
    if (count) {
        resolve("There is a count value.");
    } else {
        reject("There is no count value");
    }
});

console.log(countValue);

Output

Promise {<resolved>: "There is a count value."}
  • In the above program, a Promise object is created that takes two functions: resolve() and reject().

  • resolve() is used if the process is successful

  • reject() is used when an error occurs in the promise.

  • The promise is resolved if the value of count is true.

Working of JavaScript promise

JavaScript Promise Chaining

  • Promises are useful when you have to handle more than one asynchronous task, one after another.

  • For that, we use promise chaining.

  • You can perform an operation after a promise is resolved using methods then(), catch() and finally().

JavaScript then() method

The then() method is used with the callback when the promise is successfully fulfilled or resolved.

The syntax of then() method is:

promiseObject.then(onFulfilled, onRejected);

Example 2: Chaining the Promise with then()


// returns a promise

let countValue = new Promise(function (resolve, reject) {
  resolve("Promise resolved");
});

// executes when promise is resolved successfully

countValue
  .then(function successValue(result) {
    console.log(result);
  })

  .then(function successValue1() {
    console.log("You can call multiple functions this way.");
  });

Output

Promise resolved
You can call multiple functions this way.

In the above program, the then() method is used to chain the functions to the promise. The then() method is called when the promise is resolved successfully.

You can chain multiple then() methods with the promise.


JavaScript catch() method

The catch() method is used with the callback when the promise is rejected or if an error occurs. For example,

// returns a promise
let countValue = new Promise(function (resolve, reject) {
   reject('Promise rejected'); 
});

// executes when promise is resolved successfully
countValue.then(
    function successValue(result) {
        console.log(result);
    },
 )

// executes if there is an error
.catch(
    function errorValue(result) {
        console.log(result);
    }
);

Output

Promise rejected

In the above program, the promise is rejected. And the catch() method is used with a promise to handle the error.

Working of JavaScript promise chaining

Example : Program with a Promise

<html>
<head>
<h2> Javascript Promise</h2>
</br> </head>
<body>
<script>
var p=new Promise(function(resolve, reject){
var x= 2+3;
if(x==5)
    resolve(" executed and resolved successfully");
else
    reject("rejected");
});
 p.then(function(fromResolve){
 document.write("Promise is"+fromResolve);
 }).catch(function(fromReject){
 document.write("Promise is "+fromReject);
 });
</script>
</body>
</html>

Output:

Promise is executed and resolved successfully.

In the above Promise implementation, the Promise constructor takes an argument that callbacks the function. This callback function takes two arguments, i.e.,

  1. Resolve: When the promise is executed successfully, the resolve argument is invoked, which provides the result.

  2. Reject: When the promise is rejected, the reject argument is invoked, which results in an error.

It means either resolve is called or reject is called. Here, then() has taken one argument which will execute, if the promise is resolved. Otherwise, catch() will be called with the rejection of the promise.

JavaScript Promise Versus Callback :

  • Promises are similar to callback functions in a sense that they both can be used to handle asynchronous tasks.

  • JavaScript callback functions can also be used to perform synchronous tasks.

Their differences can be summarized in the following points:

JavaScript Promise

  1. The syntax is user-friendly and easy to read.

  2. Error handling is easier to manage.

    Example:

    
     api().then(function(result) {
         return api2() ;
     }).then(function(result2) {
         return api3();
     }).then(function(result3) {
         // do work
     }).catch(function(error) {
         //handle any error that may occur before this point 
     });
    

JavaScript Callback

  1. The syntax is difficult to understand.

  2. Error handling may be hard to manage.

    Example:

    
     api(function(result){
         api2(function(result2){
             api3(function(result3){
                  // do work
                 if(error) {
                     // do something
                 }
                 else {
                     // do something
                 }
             });
         });
     });
    

JavaScript finally() method

  • You can also use the finally() method with promises.

  • The finally() method gets executed when the promise is either resolved successfully or rejected. For example,

// returns a promise
let countValue = new Promise(function (resolve, reject) {
    // could be resolved or rejected   
    resolve('Promise resolved'); 
});

// add other blocks of code
countValue.finally(
    function greet() {
        console.log('This code is executed.');
    }
);

Output

This code is executed.

Advantages of using Promises

  1. A better option to deal with asynchronous operations.

  2. Provides easy error handling and better code readability.