Promise in JavaScript
In JavaScript, a Promise is an object representing the eventual completion or failure of an asynchronous operation and its resulting value. It allows you to handle asynchronous operations in a more manageable and readable way compared to traditional callbacks.
What is a Promise?
A Promise is an object that represents the eventual outcome of an asynchronous operation. A promise can be in one of the following states:
Pending: The initial state; the promise is still being executed and is neither resolved nor rejected.
Resolved (Fulfilled): The operation completed successfully and returned a result.
Rejected: The operation failed and returned an error.
Creating a Promise
A promise is created using the new Promise()
constructor. This constructor takes a function called the executor, which contains two arguments: resolve
and reject
.
const myPromise = new Promise((resolve, reject) => {
let success = true;
if(success) {
resolve('The operation was successful!');
} else {
reject('The operation failed!');
}
});
Here:
resolve(value)
is called when the asynchronous operation is successful, passing the result.reject(error)
is called if the asynchronous operation fails, passing the error message.
Using Promises
After creating a promise, you can use the .then()
and .catch()
methods to handle the resolved value or the error.
1. .then()
The .then()
method is used to handle the result of a resolved promise.
myPromise
.then((result) => {
console.log(result); // Output: The operation was successful!
})
.catch((error) => {
console.log(error);
});
In the above example:
The
.then()
method receives theresult
when the promise is resolved.The
.catch()
method handles any error if the promise is rejected.
2. .catch()
The .catch()
method is used to handle any errors that occur during the execution of the promise or within the .then()
chain.
myPromise
.then((result) => {
console.log(result);
})
.catch((error) => {
console.log(error); // Output: The operation failed!
});
You can also chain .then()
methods:
myPromise
.then((result) => {
console.log(result); // Output: The operation was successful!
return 'Next step';
})
.then((nextStep) => {
console.log(nextStep); // Output: Next step
})
.catch((error) => {
console.log(error);
});
Chaining Promises
Promises can be chained, meaning you can execute a sequence of asynchronous operations one after another. Each .then()
returns a new promise.
const fetchData = new Promise((resolve) => {
setTimeout(() => resolve('Data fetched'), 1000);
});
fetchData
.then((result) => {
console.log(result); // Output: Data fetched
return new Promise((resolve) => resolve('Processing data'));
})
.then((nextResult) => {
console.log(nextResult); // Output: Processing data
});
Promise All (Promise.all()
)
Promise.all()
is used to wait for multiple promises to resolve before proceeding. It takes an array of promises and returns a new promise that resolves when all of the promises have resolved.
const promise1 = new Promise((resolve) => setTimeout(() => resolve('First'), 1000));
const promise2 = new Promise((resolve) => setTimeout(() => resolve('Second'), 2000));
const promise3 = new Promise((resolve) => setTimeout(() => resolve('Third'), 1500));
Promise.all([promise1, promise2, promise3])
.then((results) => {
console.log(results); // Output: ['First', 'Second', 'Third']
})
.catch((error) => {
console.log(error);
});
If any of the promises reject, Promise.all()
will reject immediately.
Promise Race (Promise.race()
)
Promise.race()
returns a promise that resolves or rejects as soon as one of the promises in the array resolves or rejects, rather than waiting for all of them.
const promise1 = new Promise((resolve) => setTimeout(() => resolve('First'), 1000));
const promise2 = new Promise((resolve) => setTimeout(() => resolve('Second'), 2000));
Promise.race([promise1, promise2])
.then((result) => {
console.log(result); // Output: First
});
In this case, the first promise to resolve (promise1
) is the one that gets passed to the .then()
method.
Promise All Settled (Promise.allSettled()
)
Promise.allSettled()
waits for all promises to either resolve or reject, and it returns an array of objects describing the outcome of each promise. This is useful when you want to handle all promises, regardless of whether they resolve or reject.
const promise1 = new Promise((resolve) => setTimeout(() => resolve('First'), 1000));
const promise2 = new Promise((resolve, reject) => setTimeout(() => reject('Second failed'), 2000));
Promise.allSettled([promise1, promise2])
.then((results) => {
console.log(results);
// Output:
// [
// { status: 'fulfilled', value: 'First' },
// { status: 'rejected', reason: 'Second failed' }
// ]
});
Promise Any (Promise.any()
)
Promise.any()
returns a promise that resolves as soon as one of the promises resolves. If all promises reject, it returns an AggregateError
.
const promise1 = new Promise((resolve, reject) => setTimeout(() => reject('First failed'), 1000));
const promise2 = new Promise((resolve) => setTimeout(() => resolve('Second succeeded'), 2000));
Promise.any([promise1, promise2])
.then((result) => {
console.log(result); // Output: Second succeeded
})
.catch((error) => {
console.log(error);
});
Summary of Key Methods
new Promise(executor)
: Creates a new promise with an executor function..then(onSuccess, onFailure)
: Handles the resolved value or rejected error..catch(onFailure)
: Handles errors..finally()
: Executes code after the promise settles (whether it’s resolved or rejected).Promise.all([promises])
: Resolves when all promises are resolved.Promise.race([promises])
: Resolves as soon as one promise resolves or rejects.Promise.allSettled([promises])
: Resolves after all promises are settled.Promise.any([promises])
: Resolves as soon as one promise resolves; rejects if all promises fail.
Example of an Asynchronous Operation Using Promises
function fetchDataFromAPI(url) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (url === 'valid_url') {
resolve('Data fetched successfully');
} else {
reject('Failed to fetch data');
}
}, 1000);
});
}
fetchDataFromAPI('valid_url')
.then((data) => console.log(data)) // Output: Data fetched successfully
.catch((error) => console.error(error));
Promises are a powerful tool for handling asynchronous operations and can greatly simplify code that would otherwise rely on nested callbacks (callback hell).