A JavaScript Promise is an object that represents the eventual completion (or failure) of an asynchronous operation and its resulting value. Promises provide a cleaner and more intuitive way to work with asynchronous code compared to traditional callback-based approaches.
👉 Download eBook - JavaScript: from ES2015 to ES2023
.
Key Concepts
-
States: A Promise has three states:
- Pending: The initial state, neither fulfilled nor rejected.
- Fulfilled: The operation was completed successfully.
- Rejected: The operation failed.
Creating a Promise:
const myPromise = new Promise((resolve, reject) => {
// Asynchronous operation
if (/* operation successful */) {
resolve('Success!');
} else {
reject('Error!');
}
});
-
Using Promises:
-
then
: Attaches callbacks for the fulfilled case and the rejected case. -
catch
: Attaches a callback for the rejected case. -
finally
: Attaches a callback that is executed regardless of the promise's outcome.
-
myPromise
.then((value) => {
console.log(value); // "Success!"
})
.catch((error) => {
console.error(error); // "Error!"
})
.finally(() => {
console.log('Operation completed');
});
Promises in Action
Basic Example
Here's a simple example of using a Promise to simulate an asynchronous operation:
const fetchData = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
const success = true; // Simulate success or failure
if (success) {
resolve('Data fetched successfully!');
} else {
reject('Failed to fetch data.');
}
}, 2000);
});
};
fetchData()
.then((message) => console.log(message))
.catch((error) => console.error(error));
Chaining Promises
Promises can be chained to handle a sequence of asynchronous operations:
const step1 = () => Promise.resolve('Step 1 complete');
const step2 = () => Promise.resolve('Step 2 complete');
const step3 = () => Promise.resolve('Step 3 complete');
step1()
.then((result1) => {
console.log(result1);
return step2();
})
.then((result2) => {
console.log(result2);
return step3();
})
.then((result3) => {
console.log(result3);
})
.catch((error) => {
console.error(error);
});
Advanced Usage
Promise.all
Executes multiple promises in parallel and waits for all of them to be resolved or any of them to be rejected:
const promise1 = Promise.resolve('Promise 1 resolved');
const promise2 = Promise.resolve('Promise 2 resolved');
const promise3 = Promise.resolve('Promise 3 resolved');
Promise.all([promise1, promise2, promise3])
.then((values) => {
console.log(values); // ['Promise 1 resolved', 'Promise 2 resolved', 'Promise 3 resolved']
})
.catch((error) => {
console.error(error);
});
Promise.race
Waits for the first promise to be settled (resolved or rejected):
const promise1 = new Promise((resolve) => setTimeout(resolve, 500, 'First'));
const promise2 = new Promise((resolve) => setTimeout(resolve, 100, 'Second'));
Promise.race([promise1, promise2])
.then((value) => {
console.log(value); // 'Second'
})
.catch((error) => {
console.error(error);
});
Conclusion
JavaScript Promises offer a powerful way to handle asynchronous operations, making the code more readable and maintainable. By understanding and utilizing Promises effectively, developers can write cleaner and more efficient asynchronous code.