DEV Community

Cover image for JavaScript Promises Explained
Tutsmake
Tutsmake

Posted on

JavaScript Promises Explained

In this tutorial, you will learn about JavaScript promises, what are promises and how to use them.

Imagine that you have a car(šŸš—) shop. Where cars (šŸš—šŸš—šŸš—) are repaired.

And a customer (šŸ’) brings his car (šŸš—) to your repair shop. And says that my car has to be repaired. It has some problems.

Promise you that your car (šŸš—) will be repaired till evening today. Here you promise the customer. But three states are formed in it. Given below states of promise:

  • When the car(šŸš—) came to your repair center, it was in the pending state.
  • If you repair the car(šŸš—) till today evening. So your promise is resolved.
  • If the problem of the car(šŸš—) is not solved today evening, then it comes to the reject state.

Let us now explain to you the promises of JavaScript.

Intro - Promises in JavaScript

In JavaScript, a promise is an object that contains the future value of an asynchronous operation.

Sometimes, when you work with webservers and requesting some data from a webserver, the javascript promise promises us to get data from webserver and you can use in the future.

States of a Promise

javascript promises states

A promise has three states:

  • Pending: first of all, the job is in a pending state.
  • Fulfilled: A Promise is resolved if the job finished successfully.
  • Rejected: A Promise is rejected if the job an error occurred.

Note that, A promise begins in the pending state which indicates that the promise hasnā€™t completed. It finishes with either a successful or failed state.

Creating a Promise

You can see the following syntax for how to create promises using PromiseĀ constructor.

The constructor syntax for a promise object is:

let promise = new Promise((resolve, reject) => {     ...   });

To create a promise in JavaScript, you use theĀ PromiseĀ constructor, new PromiseĀ  the executor and it runs automatically. It contains the producing code which should eventually produce the result.

The promise is resolved by calling theĀ resolve()Ā and rejected by callingĀ reject().

See the following example:

let finish = true;

let res = new Promise(function (resolve, reject) {
    if (finish) {
        resolve("Your šŸš— has repaired.");
    } else {
        reject("Your šŸš— has not repaired yet.");
    }
});

TheĀ Promise constructor takes a function as an argument and this function takes two functions resolve()Ā andĀ reject().Ā 

When you call theĀ new Promise(executor), theĀ executorĀ is called automatically.Ā 

According to job state, inside the executor(new promise), you can callĀ resolve()Ā and reject()Ā function, if completed job successfully then call resolve()Ā  and if job failed then reject().

See the following example:

let finish = true;

let res = new Promise(function (resolve, reject) {
    setTimeout(() => {
        if (finish) {
            resolve("Your šŸš— has repaired.");
        } else {
            reject("Your šŸš— has not repaired yet.");
        }
    }, 5 * 1000);
});
console.log(res);

Now, you see that the promise begins with theĀ pendingĀ state with the value isĀ undefined. The promise value will be returned later once the promise is fulfilled.

After the 5 seconds timer finishes, the promise is either resolved or rejected randomly, and its value will be the value passed to the resolve or reject function. See the following:

That was an example of a job resolved.

After that, If you change the value of theĀ finishĀ variable and it value to falseĀ and run the script again:

let finish = false;

Note that, this time CallingĀ reject() state and display error messageĀ after 5 seconds.

That was an example of a job rejected.

When you create a PromiseĀ object using new PromiseĀ , this time is in pending state until it is not fulfilled state (resolved or rejected).

Consuming a Promise

You can consume promise by callingĀ then(), catch()Ā and , finally() methods on the promise.

1) TheĀ then()Ā method

TheĀ Then is called when a promise is resolved.Ā 

See the following syntax to represent then()Ā method:

promiseObject.then(onFulfilled, onRejected);

Note that, it takes two parameters:

  • TheĀ onFulfilledĀ callback is called if the promise is fulfilled.
  • TheĀ onRejectedĀ callback is called when the promise is rejected.

The following function returns aĀ PromiseĀ object:

function doPromise(finish) {
    return new Promise(function (resolve, reject) {
        setTimeout(() => {
            if (finish) {
                resolve("Your šŸš— has repaired.");
            } else {
                reject("Your šŸš— has not repaired yet.");
            }
        }, 4 * 1000);
    });
}

And the following calls theĀ doPromise()Ā function and invokes theĀ then()Ā method:

let res = doPromise(true);

res.then(
    success => console.log(success),
    reason => console.log(reason)
);

2) TheĀ catch()Ā method

TheĀ catch is called when a promise is rejected.Ā 

res.catch(
    reason => console.log(reason)
);

Internally, theĀ catch()Ā method invokes theĀ then(undefined, onRejected)Ā method.

3) TheĀ finally()Ā method

In every situtation want to execute the same piece of code whether the promise is resolved or rejected.

You can see the following example:

function carRepair() {
    // ...
}

res
    .then(
        (success) => {
            console.log(success);
            carRepair();
        }
    ).catch(
        (reason) => {
            console.log(reason);
            carRepair();
        }
    );

As you can see, theĀ carRepair()Ā function call is duplicated in bothĀ then()Ā andĀ catch()Ā methods.

To remove this duplicate and execute theĀ carRepair()Ā whether the promise is fulfilled or rejected, you use theĀ finally()Ā method, like this:

res
    .then(success => console.log(success))
    .catch(reason => console.log(reason))
    .finally(() => carRepair());

JavaScript Promise Example

In this example, we will show you how to load google news headlines from google webserver using json api.

Suppose that we have the following JSON file: https://newsapi.org/v2/top-headlines?country=us&apiKey=e03753c9126b408d870a44318813ac3d

When you call this google news api, you will looks like:

{
   "status":"ok",
   "totalResults":38,
   "articles":[
      {
        {
         "source":{
            "id":"fox-news",
            "name":"Fox News"
         },
         "author":"Daniel Canova",
         "title":"Phil Mickelson teases big plans for 'The Match,' suggests Michael Jordan, Tony Romo, others could participate - Fox News",
         "description":"Thereā€™s no doubt about it that ā€œThe Match: Champions for Charityā€ lived up to the hype.",
         "url":"https://www.foxnews.com/sports/phil-mickelson-big-plans-the-match-michael-jordan-tony-romo",
         "urlToImage":"https://static.foxnews.com/foxnews.com/content/uploads/2020/05/The-Match-Champions-for-Charity-2.jpg",
         "publishedAt":"2020-05-27T22:48:22Z",
         "content":"Thereā€™s no doubt about it that ā€œThe Match: Champions for Charityā€ lived up to the hype.\r\nThe charity golf match featuring legends Tiger Woods, Phil Mickelson, Tom Brady and Peyton Manning raised $20 ā€¦ [+2453 chars]"
      }
      }
   ]
}

The following shows the HTML page that contains a google news button. When you click the google news button, the page loads data from the google news webserver and display latest news headines:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>JavaScript Promise Demo</title>
</head>
<body>
    <div id="container">
        <button id="btnGet">Get News</button><br>
        <div id="news"> </div>
    </div>
    <script src="">
    </script>
</body>
</html>

To load google news headlines from google news webserver, weā€™ll use theĀ XMLHttpRequestĀ object. Later, you will learn how to use theĀ fetch()Ā method.

The following function returns a Promise object that loads data from a remote file:

function load(url) {
    return new Promise(function (resolve, reject) {
        const request = new XMLHttpRequest();

        request.onreadystatechange = function (e) {
            if (this.readyState === 4) {
                if (this.status == 200) {
                    resolve(this.response);
                } else {
                    reject(this.status);
                }
            }
        }
        request.open('GET', url, true);
        request.responseType = 'json';
        request.send();
    });
}

Inside the new promise, callĀ resolve()Ā function and passed in the response if the HTTP status code is 200, otherwise, we invoked theĀ reject()Ā function and passed in the HTTP status code.

Register the button click event listener and call theĀ then()Ā method on the Promise. If the load is successful, then show google news headlines from the google news web server. Otherwise, we show the error message with the HTTP status code.

const btn = document.querySelector('#btnGet');
const msg = document.querySelector('#news');
btn.onclick = function () {
    load('https://newsapi.org/v2/top-headlines?country=us&apiKey=e03753c9126b408d870a44318813ac3d')
        .then(function(data) {
       
        for (i = 0; i < data.articles.length; i++) {
              var node = document.createElement("LI");
              var textnode = document.createTextNode(data.articles[i].title);
              node.appendChild(textnode);
              document.getElementById("news").appendChild(node);
        }
       
    });
}

See the following output, when you call this api using js promise:

Conclusion

In this tutorial you have learned the following:

  • A promise is an object that returns a value in the future.
  • How to create a promise in javascript.
  • How to call promise with differents states.
  • A promise begins in the pending state and finishes in either fulfilled state or rejected state.
  • TheĀ then is called when a promise is resolved.Ā 
  • TheĀ catch is called when a promise is rejected.Ā 
  • finally()Ā method execute piece of code, whether the promise is resolved or rejected.
  • Call google news api and display news headlines using the js promises

Top comments (0)