Table of contents
1.
Introduction 
2.
What is a JavaScript promise?
3.
Syntax
4.
How JavaScript Promises Work?
5.
Creating a JavaScript Promise 
5.1.
Code
6.
Consuming a JavaScript Promise 
6.1.
Code
7.
JavaScript Promise Chaining
7.1.
Code
7.2.
Code
7.3.
Code
8.
JavaScript Promises Method
9.
Frequently Asked Questions
9.1.
What is the promise method?
9.2.
Is JavaScript promise synchronous or asynchronous?
9.3.
Is Promise a class in JavaScript?
9.4.
What are the 3 promises in JavaScript?
10.
Conclusion
Last Updated: Dec 12, 2024
Easy

Understanding JavaScript Promises

Author Hari Sapna Nair
2 upvotes
Career growth poll
Do you think IIT Guwahati certified course can help you in your career?

Introduction 

Javascript is a synchronous programming language where instructions are blocked until the current task is completed. But there might be cases where we don't want the program execution to wait, like making an API(Application Programming Interface) call to fetch data. In these cases where asynchronous operations have to be performed, we use Callback, Promises, and async-await

Understanding JavaScript Promises

Before JavaScript promises were introduced, callbacks were used to perform asynchronous operations. But over the years, JavaScript promises replaced callback functions and are now considered the effective method to handle asynchronous operations. 
 

This blog will cover the concept of JavaScript Promises in detail, along with some examples and frequently asked questions.

Also Read, Javascript hasOwnProperty

What is a JavaScript promise?

A Javascript promise is similar to a promise in real life. When we make a promise in real life, it guarantees that we will do something in the future. A promise has two possible outcomes: it will be kept when the time comes or won't. The same is true for promises in JavaScript. When a JavaScript promise is defined, it will be resolved when the time comes or rejected.

 

JavaScript promises are objects that represent the eventual completion or failure of an asynchronous operation. It is a means of assurance that a particular operation will occur shortly. Though, the promise doesn't need to be fulfilled every time. For example, if there is a network error, the promise won't be fulfilled.

 

A JavaScript Promise object contains both the producing code and calls to the consuming code. Let's have a look at the syntax of JavaScript Promises.
 

Syntax

let promise = new Promise(function (resolve, reject) {
 // Producing code which may take some time

 // Successful
 resolve();

 // Error
 reject();
});

// Consuming code must wait for a fulfilled Promise
promise.then(
 function (value) {
   // Successful
 },
 function (error) {
   // Error 
 }
);

 

When the above code is executed, a result is obtained which calls one of the two callback functions.

How JavaScript Promises Work?

The JavaScript Promise object supports two properties: state and result. Let's have a look at them.

1. Definition: A JavaScript Promise is an object representing the eventual completion or failure of an asynchronous operation.

2. States:

  • Pending: The initial state, neither fulfilled nor rejected.
  • Fulfilled: The operation completed successfully.
  • Rejected: The operation failed.

3. Creation: A promise is created using the new Promise() constructor, which takes a function with resolve and reject as parameters:

let promise = new Promise((resolve, reject) => {    
// Async operation    
if (success) resolve(result);    
else reject(error); 
});

4. Then Method: The then() method is used to define what happens when the promise is fulfilled or rejected:

promise.then(    
(result) => console.log("Success:", result),    
(error) => console.log("Error:", error) 
);

5. Chaining: Promises can be chained, allowing multiple asynchronous operations to be executed in sequence:

promise    
.then(result => process(result))    
.then(processedResult => finalStep(processedResult))    
.catch(error => handleError(error));

6. Catch Method: The catch() method is used for handling errors in promise chains:

promise.catch(error => console.log("Caught error:", error));

7. Finally Method: The finally() method executes code after the promise is settled, regardless of success or failure:

promise.finally(() => console.log("Completed"));

For example, if we request some data from the server using a Promise, it will be pending until the data is received. When we receive the data from the server successfully, the promise will be in the resolved state. If we don't receive any data, the promise will be in the rejected state. 

 

If there are multiple requests, after the first promise is resolved or rejected, a new process is attached to it directly. This is called chaining, which will be discussed in the latter part of this blog.

 

Representation of the process of Promises

 

Creating a JavaScript Promise 

Let's create our first JavaScript Promise. To create a Promise object, we make use of a constructor. It takes two parameters, one for the success case(resolve) and the other for the failure case(reject). Then we use the if-else statement to specify what to do in the success and failure case. If the given condition is met, the promise will be resolved. Otherwise, it will be rejected.

Code

// Creating a promise
const promise = new Promise((resolve, reject) => {
 let promiseKept = true;
 
 // Promise successful
 if (promiseKept) {
   const yesParty = "Gave friends a party!!!";
   resolve(yesParty);
 }
 
 // Promise failed
 else {
   const noParty = "Didn't give friends a party!!!";
   reject(noParty);
 }
});

Consuming a JavaScript Promise 

Now let's use the promise we have created. If you revisit the image at the beginning of this blog, you'll see two cases: resolved and rejected. If the promise is resolved, the .then() method is called. Else if the promise is rejected, it will jump to the catch( ) method.

Code

// Consuming a promise
const checkIfPartyGiven = () => {
 promise
   // Promise successful
   .then((value) => {
     console.log(value);
   })
   
   // Promise failed
   .catch((err) => {
     console.error(err);
   });
};

 

Let's execute the above code by calling the checkIfPartyGiven() function. 

 

Code:

checkIfPartyGiven();

 

Output:

Gave friends party!!!

 

As the above promise is resolved the following message is obtained.

JavaScript Promise Chaining

If there are multiple asynchronous operations to be done and if we try to use Callbacks for them, we'll find ourselves inside a situation called the Callback hell. This situation is solved using promise chaining.

 

Before going to promise chaining, let's look how a callback hell would look like.

Code

// Callback hell
functionA(function (resultFromA) {
 functionB(
   resultFromA,
   function (resultFromB) {
     functionC(
       resultFromB,
       function (resultFromC) {
         functionD(
           resultFromC,
           function (resultFromD) {
             functionE(
               resultFromD,
               function (resultFromE) {
                 console.log(resultFromE);
               },
               errorCallBack
             );
           },
           errorCallBack
         );
       },
       errorCallBack
     );
   },
   errorCallBack
 );
}, errorCallBack);

 

As you can see, the above code is difficult to read and understand. Also, handling errors in the case of callbacks can be challenging. To overcome this issue, we make use of the promises. 

 

Let's see how the above code would look using promises.

Code

// Promise chaining
functionA()
 .then(function (resultFromA) {
   return functionB(resultFromA);
 })
 .then(function (resultFromB) {
   return functionC(resultFromB);
 })
 .then(function (resultFromC) {
   return functionD(resultFromC);
 })
 .then(function (resultFromD) {
   return functionE(resultFromD);
 })
 .catch(errorCallBack);

 

The code becomes much simplified in promises. This is because we are attaching callbacks rather than passing them. Now the code looks cleaner and easier to understand.

 

"JavaScript promises can save you from the callback hell."

 

Let's now see an example of promise chaining.

Code

// Using promises

// First promise
const firstPromise = () => {
 return new Promise((resolve, reject) => {
   setTimeout(() => {
     const flag = true;
     if (flag) {
       resolve("Hello!!!");
     } else {
       reject("Error");
     }
   }, 1000);
 });
};

// Second promise
const secondPromise = () => {
 return new Promise((resolve, reject) => {
   setTimeout(() => {
     const flag = true;
     if (flag) {
       resolve("Welcome to Coding Ninjas");
     } else {
       reject("Error");
     }
   }, 1000);
 });
};

const greetPromise = () => {
 firstPromise()
   .then((value1) => {
     console.log(value1);
     return secondPromise();
   })
   .then((value2) => {
     console.log(value2);
   })
   .catch((err) => {
     failureCallback();
   });
};

 

The code above shows how multiple callbacks can be chained one after another.
 

 

Output

 

Practice by yourself with the help of an online JS editor.

Promise chaining is used in many scenarios in the real world. For example, it is used to fetch resources from an API. The resources are fetched, and a chain of promises is created to execute when the resource is fetched. 

JavaScript Promises Method

Some of the frequently used promises methods are as follows:-

MethodDescription
all(iterable)It waits for all promises to be resolved or any one of them to be rejected.
allSettled(iterable)It waits until all promises are either resolved or rejected.
any(iterable)It returns the promise value as soon as any one of the promises is fulfilled.
race(iterable)It waits until any one of the promises is rejected or resolved.
reject(reason)It returns a new Promise object that is rejected for the given reason.
resolve(value)It returns a new Promise object that is resolved with the given value.
finally()It returns a promise when a promise is either fulfilled or rejected.

Frequently Asked Questions

What is the promise method?

The Promise method in JavaScript is used to handle asynchronous operations, allowing chaining with then(), catch(), and finally() for success or failure handling.

Is JavaScript promise synchronous or asynchronous?

JavaScript promises are asynchronous, allowing non-blocking operations and letting the rest of the code run while waiting for the promise to settle.

Is Promise a class in JavaScript?

Yes, Promise is a built-in class in JavaScript that represents the eventual result of an asynchronous operation, which can be either fulfilled or rejected.

What are the 3 promises in JavaScript?

The three main states of a JavaScript promise are:

  1. Pending: Initial state, neither fulfilled nor rejected.
  2. Fulfilled: The operation was successful.
  3. Rejected: The operation failed.

Conclusion

JavaScript promises are a powerful tool for managing asynchronous operations, allowing developers to handle success and failure more efficiently. By understanding promise states—pending, fulfilled, and rejected—and using methods like then(), catch(), and finally(), developers can write cleaner, more readable code. Promises enable better error handling and offer a robust mechanism for chaining asynchronous tasks, making them a fundamental part of modern JavaScript development.

Live masterclass