A Promise in JavaScript is an object that represents the eventual completion or failure of an asynchronous operation and its resulting value. A Promise can be in one of three states:
Once a promise is fulfilled or rejected, it is said to be settled. A settled promise cannot change its state again.
Here is a simple example of creating a Promise:
const myPromise = new Promise((resolve, reject) => {
// Simulate an asynchronous operation
setTimeout(() => {
const randomNumber = Math.random();
if (randomNumber < 0.5) {
resolve(randomNumber); // Fulfill the promise
} else {
reject(new Error('Random number is greater than or equal to 0.5')); // Reject the promise
}
}, 1000);
});
.then()
and .catch()
The .then()
method is used to handle the fulfillment of a promise, and the .catch()
method is used to handle the rejection.
myPromise
.then((result) => {
console.log('Promise fulfilled with result:', result);
})
.catch((error) => {
console.error('Promise rejected with error:', error.message);
});
.finally()
The .finally()
method is called regardless of whether the promise is fulfilled or rejected.
myPromise
.then((result) => {
console.log('Promise fulfilled with result:', result);
})
.catch((error) => {
console.error('Promise rejected with error:', error.message);
})
.finally(() => {
console.log('Promise operation is complete.');
});
Promise.all()
The Promise.all()
method takes an array of promises and returns a new promise that resolves when all of the input promises have resolved, or rejects as soon as one of them rejects.
const promise1 = Promise.resolve(1);
const promise2 = Promise.resolve(2);
const promise3 = Promise.resolve(3);
Promise.all([promise1, promise2, promise3])
.then((results) => {
console.log('All promises fulfilled:', results);
})
.catch((error) => {
console.error('One of the promises rejected:', error);
});
Promise.race()
The Promise.race()
method takes an array of promises and returns a new promise that resolves or rejects as soon as one of the input promises resolves or rejects.
const promiseA = new Promise((resolve) => setTimeout(() => resolve('Promise A'), 200));
const promiseB = new Promise((resolve) => setTimeout(() => resolve('Promise B'), 100));
Promise.race([promiseA, promiseB])
.then((result) => {
console.log('The winning promise:', result);
})
.catch((error) => {
console.error('One of the promises rejected:', error);
});
Promises can be chained together to perform a series of asynchronous operations in sequence.
function asyncOperation1() {
return new Promise((resolve) => {
setTimeout(() => {
resolve('Result of operation 1');
}, 1000);
});
}
function asyncOperation2(result1) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(result1 + ' -> Result of operation 2');
}, 1000);
});
}
asyncOperation1()
.then((result1) => {
return asyncOperation2(result1);
})
.then((finalResult) => {
console.log('Final result:', finalResult);
})
.catch((error) => {
console.error('Error:', error);
});
It’s important to handle errors properly in promise chains. A single .catch()
at the end of the chain can catch errors from any of the promises in the chain.
Promises help to avoid callback hell by providing a more linear and readable way to handle asynchronous operations. Instead of nesting callbacks, use promise chaining.
Make sure to handle the rejection of every promise using .catch()
or by passing a rejection handler to .then()
. Otherwise, unhandled promise rejections can lead to hard - to - debug issues.
A promise should represent a single asynchronous operation. Avoid mixing multiple unrelated asynchronous operations in a single promise.
Promises are a powerful feature in JavaScript for handling asynchronous operations. They provide a more structured and readable alternative to traditional callback - based approaches. By understanding the fundamental concepts, usage methods, common practices, and best practices of promises, developers can write more robust and maintainable asynchronous code.