Asynchronous code used to be a pain to write in JavaScript. To write asynchronous operations in your code, you would have to deal with multiple levels of callback functions. The more functions that you introduced into your code, the harder it was to read.
In ES6, promises came to the rescue. Promises are a way to write asynchronous code efficiently in JavaScript.
In this guide, we’re going to talk about what promises are and how they work. We’ll walk through an example of a promise to help you learn how to use them in your code. Let’s get started!
What is a Promise?
A promise is an object that returns a response that you want to receive in the future.
A good way to think about JavaScript promises is to compare them to how people make promises. When you make a promise, it is an assurance that you are going to do something at a future date. You are not going to do that thing now; you will do it at some point later on.
A promise can exist in one of three states:
- Pending: A promise has not yet been completed.
- Rejected: A promise has failed to return a value.
- Fulfilled: A promise has been completed.
This is similar to promises in real life. You can have a pending promise which you say you are going to carry out in the future. You can fulfill a promise. You can reject, or “break” a promise, and not follow through on what you have agreed to do.
When you make a promise, it will be pending. The promise will exist in this state until a response is received and the promise is either fulfilled or rejected.
How to Create a JavaScript Promise
We’re going to start by creating a promise which returns a user’s name. This function will return a user’s name to our program after three seconds. This will help us see how promises are used to write asynchronous code.
To create a promise, we need to create a Promise object:
new Promise((resolve, reject) => { // Your code here });
Promises accept two arguments: a function that handles the success of the promise and a function that handles a failed promise. This means that our promise will return different values depending on its outcome.
A promise should contain an “if” statement that determines whether a promise has executed successfully. If a promise has not executed successfully, it should return a rejected state promise:
new Promise((resolve, reject) => { if (value is true) { resolve(); } else { reject(); } });
Open a new JavaScript file and copy in the following code:
let returnName = new Promise((resolve, reject) => { let name; setTimeout(() => { name = "Cinnamon"; if (name === "Cinnamon") { resolve(name); } else { reject("This promise has failed."); } }, 3000); });
This code returns the name Cinnamon
to our main program when we call the promise. This code takes three seconds to run, or 3,000 milliseconds. This means that when we call our promise it will be pending for three seconds. After the promise is settled, a resolved or rejected promise will be returned to our main program.
If “name” is equal to “Cinnamon”, our promise is resolved successfully; otherwise, our promise will be rejected. In this example, “name” is set to “Cinnamon”. Because we have specified a name, our promise resolves itself.
then() and catch() with Promises
Our code does not execute yet. We have to call our promise object:
returnName.then(data => { console.log(data); });
The then()
keyword allows us to retrieve a response from our promise. It is called after the promise is resolved. In this example, we print out the contents of data
, which is the response returned from our promise, to the console.
Our code returns: Cinnamon.
then()
only handles successful promises. What happens if our promise is rejected? That’s where the catch()
method comes in.
You can state multiple then()
statements inside a promise. This is called promise chaining. Let’s use an example to illustrate how chaining works:
returnName.then(data => { console.log(data); }).then(() => { console.log("This function is over!");
This code will return:
Cinnamon
This function is over.
then() statements are executed in the order they are specified inside a promise constructor.
The catch()
method is attached to a promise like the then()
method. Let’s create a handler which manages a rejected promise for our name example:
returnName.then(data => { console.log(data); }).catch(error => { console.log(error); });
We have tacked on a catch()
statement after our then()
statement. Notice that we use a semicolon (;) at the very end of our promise code. You should not specify a semicolon after the then()
method if you are using catch()
. This will tell JavaScript that then() and catch() are separate, and so an error will be returned in your code.
If our promise is rejected, the contents of the catch() statement will run.
"Career Karma entered my life when I needed it most and quickly helped me match with a bootcamp. Two months after graduating, I found my dream job that aligned with my values and goals in life!"
Venus, Software Engineer at Rockbot
Let’s see what happens when we run our code:
Cinnamon
The value Cinnamon
is returned because our promise resolves successfully. If the value of “name” was not “Cinnamon” in our promise, an error would be returned:
Uncaught (in promise) This promise has failed.
We specified the error message: “This promise has failed.” in our reject() function inside our promise.
finally() with Promises
What happens if you want to execute a block of code after a promise has executed, irrespective of whether the promise succeeded or failed?
That’s where the finally()
statement comes in handy. The finally()
statement runs whether or not a promise is fulfilled or rejected. Let’s update our promise call to use a finally statement:
returnName.then(data => { console.log(data); }).catch(error => { console.log(error); }).finally(() => { console.log("The returnName promise has been executed."); });
Our code returns:
Cinnamon
The returnName promise has been executed.
Our promise returns Cinnamon
because it was successful. The contents of the finally()
statement are then executed, which returns another message to our console.
Conclusion
JavaScript promises allow you to write clean asynchronous code.
In this guide, we have covered the fundamentals of promises. There is a lot more to promises than we have covered in this guide. The next step in your learning journey is to write a few promises in your own code.
Here’s a challenge: write a promise which makes a web request and returns its response. To do this, you will want to use the fetch() API to make a request. This request should be enclosed within a promise. You should write code that handles the promise both if it succeeds or fails.
If you want to go further, check out JavaScript async functions. These can be used to write asynchronous code and are commonly used with Promises.
Now you’re ready to start writing JavaScript promises like an expert!
About us: Career Karma is a platform designed to help job seekers find, research, and connect with job training programs to advance their careers. Learn about the CK publication.