Promises are a key feature in JavaScript that allow for asynchronous code execution and handling of asynchronous operations. Promises are essentially objects that represent the eventual completion (or failure) of an asynchronous operation and allow us to handle the result once it’s available.
What are Promises?
Promises are objects that represent the eventual completion (or failure) of an asynchronous operation and its resulting value. A promise can be in one of three states: pending
, fulfilled
, or rejected
.
When a promise is pending
, it means that the asynchronous operation is still executing and the promise has not yet been resolved.
When a promise is fulfilled
, it means that the asynchronous operation completed successfully and the resulting value is available.
When a promise is rejected
, it means that the asynchronous operation failed and an error is available.
Promises are used extensively in JavaScript for handling asynchronous operations such as fetching data from a server, reading from a file, or performing a long-running calculation. Promises provide a clean and consistent API for working with asynchronous operations and allow for more readable and maintainable code.
Creating a Promise
Creating a promise is easy. Simply call the Promise
constructor and pass a function as an argument. This function, called the executor
, takes two parameters: resolve
and reject
. These two parameters are functions that are called when the asynchronous operation is complete, either successfully or with an error.
Here’s an example of creating a promise that resolves with a value:
const promise = new Promise((resolve, reject) => {
// perform some asynchronous operation
setTimeout(() => {
resolve("hello world");
}, 1000);
});
promise.then((result) => {
console.log(result); // prints "hello world"
});
In this example, we’re creating a new promise that performs a setTimeout
function with a delay of 1 second. When the timeout is complete, the resolve
function is called with the value 'hello world'
. The promise is then "fulfilled"
with this value.
We can also create a promise that rejects with an error:
const promise = new Promise((resolve, reject) => {
// perform some asynchronous operation
setTimeout(() => {
reject(new Error("something went wrong"));
}, 1000);
});
promise.catch((error) => {
console.error(error); // prints the error message
});
In this example, we’re creating a new promise that performs a setTimeout
function with a delay of 1 second. When the timeout is complete, the reject
function is called with an error object. The promise is then "rejected"
with this error.
Chaining Promises
One of the most powerful features of promises is the ability to chain them together. This allows us to perform a sequence of asynchronous operations in a readable and maintainable way.
We can chain promises using the then
method, which takes a function as an argument. This function is called when the promise is fulfilled, and its return value is used to create a new promise. This new promise is then returned by the then
method, allowing us to chain additional then
methods.
Here’s an example of chaining promises:
const fetchData = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve({ data: [1, 2, 3] });
}, 1000);
});
};
fetchData()
.then(result => {
return new Promise((resolve, reject) => {
setTimeout(() => {
const newData = result.data.map(value => value * 2);
resolve({
data: newData
});
}, 1000)})
.then(result => {
console.log(result.data); // prints "[2, 4, 6]"
});
In this example, we’re defining a function called fetchData
that returns a promise that resolves with an object containing an array of numbers. We then chain two then
methods to this promise. The first then
method takes the result of the previous promise and creates a new promise that resolves with a new object containing an array of numbers that are double the original numbers. The second then
method takes the result of the second promise and logs the resulting array to the console.
Handling Errors
When working with promises, it’s important to handle errors properly. If a promise is rejected, we can use the catch
method to handle the error. The catch
method takes a function as an argument that is called when the promise is rejected. This function should handle the error in an appropriate way, such as logging an error message or displaying a user-friendly error message.
const fetchData = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error("something went wrong"));
}, 1000);
});
};
fetchData()
.then((result) => {
console.log(result); // this code will not run
})
.catch((error) => {
console.error(error.message); // prints "something went wrong"
});
In this example, we’re defining a function called fetchData
that returns a promise that rejects with an error object. We then chain a then
method to this promise, which will not be executed because the promise is rejected. Instead, the catch
method is called with the error object, and we log the error message to the console.
Thank you for reading, and let’s have conversation with each other
Thank you for reading my article. Let’s have conversation on Twitter and LinkedIn by connecting.