Promises in ES6: How to Use Javascript Promise

The Promise object represents an asynchronous operation’s eventual completion (or failure) and its resulting value. Promises are natively available in ES6. However, it is also available in 3rd party libraries like fetch, which is used in HTTP or AJAX calls.

What is Promise in Javascript?

The promise is the Object of any particular asynchronous action. Promises are results of eventual operations, and it is Object. This Object has three states.

A Promise is a proxy for a value not necessarily known when the promise is created. It allows you to associate handlers with an asynchronous action’s eventual success value or failure reason.

  1. Pending State
  2. Fulfilled State
  3. Rejected State

I will explain it to you individually, but first, let me tell you its syntax.

Syntax

let promise = new Promise((resolve, reject) =>  {
        // here async actions are performed
        resolve('your result');
});

// in case of success
promise.then((resolve) => console.log(resolve));

//in case of fail or an error
promise.catch((reject) => console.log(reject));

In promise, we have to pass two arguments to its constructor,

  1. resolve
  2. reject

We do not know whether the promise will resolve or reject because asynchronous calls will take milliseconds to execute the promises. This is because asynchronous calls are simply AJAX calls, which will take some time to execute and get a response from the server. So by that time, the state will be pending.

Pending State

While the Asynchronous task is performed, the promise object holds, which does not contain any value. Instead, it will return a promise that at any time in the future, it will get either resolved or rejected with an error. This state is called a Pending state.

Resolve or Fulfilled State

If the operation of the Asynchronous task is completed, it will be resolved, and you can get its value by calling the then() function on the promise object.

let promise = new Promise((resolve, reject) =>  {
        resolve('hello world');
});
promise.then((resolve) => console.log(resolve));

I am not performing any asynchronous call in the above example, just showing you a syntactical example.

Rejected State

If the operation of the Asynchronous task is not completed successfully and an error occurs or is thrown, then It will be dismissed, and you can get the error value by calling the catch() function on the promise object.

let promise = new Promise((resolve, reject) =>  {
        reject('an error occured');
});
promise.then((reject) => console.log(reject));

Example #1

//main.js

let promise = new Promise((resolve, reject) =>  {
        setTimeout(() => {
            resolve('Promises are working')
        }, 2000);
});
promise.then((data) => {
    console.log(data);
});

If you run the above code in the browser, you might face the following issue.

Possible Errors

  1. You can get any syntax errors.
  2. If you perform code directly in your browser, then chances are very high to fail the webpack compilation process.

Possible Solutions

  1.  Beginner’s Guide To Setup ES6 Development Environment  Follow this article strictly and put the above code in the main.js file.

Output

Promises are working //after 2 seconds

Here in the above example, we have to use the setTimeout function to delay output so that it will behave as an asynchronous task. After 2 seconds, the promise will resolve and execute the callback function, which is accessible on the promise object.

This callback has the data returned from the Asynchronous Task. So, it is passed as an argument, and then we have the log that value and output will be above statement.

let promise = new Promise((resolve, reject) =>  {
        setTimeout(() => {
            reject('Aww there is something wrong')
        }, 2000);
});
promise.catch((error) => {
    console.log(error);
});

In this scenario, an Asynchronous task will give an error, and we can call the catch method on a promise object, take an argument as an error, and log that error.

Output

Aww there is something wrong //after 2 seconds

Example #2

//main.js

let prom = () => {
    return new Promise((resolve, reject) =>  {
        setTimeout(() => {
            resolve(3);
            if(1){
                reject('error');
            }
        }, 1000);
    });
}
prom().catch(error => console.log(error));
prom().then(data =>console.log(data));

Output

3 //after 1 second

Here, first, we create a function that returns a promise, and then depending on success or failure, we have called then() and catch() (methods, respectively).

If you closely look at the example, whichever event occurs first, like if the resolve() is called first, then the respective then() method is called, and if the reject() method is called, then the respective catch() method will be executed.

Callback Hell

Promises and Callbacks are pretty much the same but differ in one term called “Callback Hell.” If you compose more than two callbacks, things get complicated, and you will end up with messy code.

Promises are composable, so we can create multiple promises and pass them to only one function, and they will get resolved or rejected. And also, it removes the callback hell problem.

Let’s take an example of what is called callback hell.

//main.js

let mj = 'KingOfPop';
let prom = (data, callbackFunction) => {
    callbackFunction(null,data);
}
prom(mj, (error, data) => {
    console.log(data);
    prom(mj, (error, data) => {
        console.log(data);
        prom(mj, (error, data) => {
            console.log(data);
        });
    });
});

Output

KingOfPop
KingOfPop
KingOfPop

In the above example, I have used callbacks instead of Promises. So the callback hell is created because we call prom function, and then again, when it completes, we call another and another, so a pyramid of doom is called callback hell. We can also get the same output using Promises.

//main.js

let prom = (data) => {
    return new Promise((resolve, reject) => {
        if(data){
            resolve(data)
        }
        reject('An Error occured');
    });
}
Promise.all([
    prom('KingOfPop'),
    prom('KingOfPop'),
    prom('KingOfPop')
]). then(data => data.forEach(d => console.log(d)));

KingofPop
KingOfPop
KingofPop

So, we can compose multiple promises, which will then resolve or reject depending on the result. It is very cool. In the above examples, I have not used Asynchronous Code because I am leaving it to you to perform faking ajax requests or use the timeout function on your own and see the magic.

Promises In ES6
Promises In ES6

Key points

  1. Promises are a way of saying that till now, I have not any data while in a pending state, but in the future, It will indeed either resolve or reject the data depending on the result.
  2. We can use multiple promises and compose them in a way that we can remove a callback hell problem.
If you still have doubts, then ask in the comment below. I am happy to help you out.

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.