What Is JavaScript Promise? And How To Use It?
February 14, 2023
Promise is a new feature in ES6, and it is used to optimize the previous callback function. This interview in-depth discussion will discuss what promise is, why we need Promise, and extend to async/await related questions.
Why Do We Need Promise?
Before we discuss Promise, let's first look at why we need it to appear.
There is an important concept in JavaScript - asynchronous (async), which allows us to execute time-consuming tasks without waiting for the program to complete, but to continue executing the following code until the task is completed and notified. Common asynchronous operations include: file operations, database operations, AJAX, and timers.
In JavaScript, there are two ways to implement asynchronous:
First: callback function
Before ES6 promise appeared, callback function was usually used to implement asynchronous operations. However, the use of callback function callback has a clear disadvantage. When multiple asynchronous operations are required, the code will continue to nest, which is usually called "callback hell".
callback(() => {
console.log("Hello!");
callback(() => {
console.log("Hello!");
callback(() => {
console.log("Hello!");
callback(() => {
console.log("Hello!");
}, 200);
}, 200);
}, 200);
}, 200);
To solve this problem, the second method - promise, was born.
What Is Promise?
In the previous section, we discussed the reason why Promise appeared. In this section, let's see what Promise is.
Promise represents a value that may be available now, in the future, or never. It is a way to handle asynchronous operations. In the MDN document, Promise is used to represent the eventual completion (or failure) and its resulting value of an asynchronous operation.
How To Use Promise?
Promise is a constructor function, which we need to create a Promise through the new keyword. And Promise will receive a function as a parameter, which is called executor, and executor will be executed immediately. As shown in the following code, if you run it in the browser developer tool, the result will be printed immediately.
new Promise((resolve, reject) => {
console.log("executor execute immediately"); // executor execute immediately
});
And executor function will receive another two function parameters
- resolve:If the request is successful, the resolve function will be called, and the result will be returned.
- reject:If the request fails, the reject function will be called, and the result will be returned.
function requestData(url) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (url === "explainthis.io") {
resolve("hello welcome to explainthis");
} else {
reject("it is not explainthis");
}
}, 3000);
});
}
// 1. Request success
requestData("explainthis.io").then((res) => {
console.log(res); //hello welcome to explainthis
});
// 2. Request failed
requestData("explainthis.com").catch((e) => console.log(e)); //it is not explainthis
Promise Status
Each Promise will be in one of the following three states:
- pending:The initial state, the executor has been executed, but is still waiting.
- fulfilled:Indicates that the operation is complete, and the resolve function is executed.
- rejected:Indicates that the operation failed, and the reject function is executed.
then
Method
- Multiple calls
Like we mentioned before, callback hell is a common problem when using callback function. Promise can solve this problem. Let's see how to use Promise to solve the problem of callback hell.
We can use the then
method to get the result of the Promise. The then
method can be called multiple times, and the result of the previous then will be passed to the next then
as a parameter.
function requestData(url) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (url === "explainthis.io") {
resolve("hello welcome to explainthis");
} else {
reject("it is not explainthis");
}
}, 3000);
});
}
requestData("explainthis.io")
.then((res) => {
console.log(res); //hello welcome to explainthis
return 1;
})
.then((res) => {
console.log(res); // 1
return 2; //hello welcome to explainthis
})
.then((res) => {
console.log(res); // 2
});
- The
then
method can accept two parameters, one is the success callback, and the other is the failure callback.
function requestData(url) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (url === "explainthis.io") {
resolve("hello welcome to explainthis");
} else {
reject("it is not explainthis");
}
}, 0);
});
}
requestData("explainthis.com").then(
(res) => {
console.log(res);
},
(reason) => {
console.log(reason);
}
);
//it is not explainthis
catch
Method
One of the advantages of Promise is error handling. The simplest way is to add a catch
to catch the error and execute some error handling code. As shown in the following code, if the request fails, for example, due to network failure, the Promise will be rejected. In this case, the catch
method will capture the error and output the error message.
fetch("https://explainthis.com/data")
.then((response) => response.json())
.then((data) => {
console.log(data);
})
.catch((error) => {
console.error("oops!", error);
})
.finally(() => {
console.log("close loader");
});
finally
Method
The finally
method will be executed regardless of whether the Promise is resolved or rejected. finally
is a very useful method in the Promise processing process. It can help us execute some necessary operations regardless of whether the Promise is successful or not.
The use case is that when you enter the page, you need to fetch data from the server. At the same time, you will display the loading screen. Finally, no matter whether you get the data or not, you need to close the loader. In this case, the logic of closing the loader is very suitable for finally. As shown in the following code:
fetch("https://explainthis.com/data")
.then((response) => response.json())
.then((data) => {
console.log(data);
})
.catch((error) => {
console.error(error);
})
.finally(() => {
console.log("close loader");
});
What Is async/await?
async/await is a syntax sugar based on Promise, which is more like synchronous operation than Promise.
First, we will use the async keyword to mark the function as an asynchronous function, and the asynchronous function is a function that returns a Promise object.
In the asynchronous function, we can call other asynchronous functions, but not use then(), but use the await syntax, which will wait for the Promise to complete and then return the final result directly.
async function getData() {
const res = await fetch("https://getsomedata");
const data = await res.json();
console.log(data);
}
getData();