JavaScript promises are a fundamental feature for managing asynchronous operations. They simplify callbacks, making code more readable and maintainable. In this post, we’ll break down promises, discuss how they work, and look at practical examples that you can apply in your projects.
What is a Promise?
A promise is an object representing the eventual completion (or failure) of an asynchronous operation and its resulting value. Think of it as a placeholder for a value that will exist in the future.
Promises have three states:
1.Pending: The promise is still in progress.
2.Fulfilled: The promise has successfully resolved.
3.Rejected: The promise has failed with an error.
Creating a Promise
Here’s how you can create and use a promise:
const fetchData = new Promise((resolve, reject) => {
const data = "Sample Data";
if (data) {
resolve(data); // Successfully resolved
} else {
reject("No data available."); // Rejected with an error
}
});
fetchData
.then((result) => {
console.log(`Data fetched: ${result}`);
})
.catch((error) => {
console.error(`Error fetching data: ${error}`);
});
Chaining Promises
Promises can be chained to perform multiple asynchronous operations in sequence:
function stepOne() {
return new Promise((resolve) => {
setTimeout(() => resolve("Step One Completed"), 1000);
});
}
function stepTwo() {
return new Promise((resolve) => {
setTimeout(() => resolve("Step Two Completed"), 1000);
});
}
stepOne()
.then((result) => {
console.log(result);
return stepTwo();
})
.then((result) => {
console.log(result);
});
In this example, each promise waits for the previous one to resolve before continuing.
Using Promise.all for Concurrent Operations
When you need to execute multiple promises concurrently, Promise.all is your friend. It runs all promises simultaneously and waits for all of them to resolve.
const fetchUser = () =>
new Promise((resolve) => setTimeout(() => resolve("User fetched"), 1000));
const fetchOrders = () =>
new Promise((resolve) => setTimeout(() => resolve("Orders fetched"), 2000));
Promise.all([fetchUser(), fetchOrders()])
.then((results) => {
console.log(results); // ["User fetched", "Orders fetched"]
})
.catch((error) => {
console.error(`Error: ${error}`);
});
Error Handling with Promises
Always use .catch or try-catch (with async/await) to handle errors effectively:
const fetchData = () =>
new Promise((resolve, reject) => {
setTimeout(() => reject("Something went wrong"), 1000);
});
fetchData()
.then((result) => {
console.log(result);
})
.catch((error) => {
console.error(`Error occurred: ${error}`);
});
With async/await:
async function fetchDataAsync() {
try {
const result = await fetchData();
console.log(result);
}
catch (error) {
console.error(`Error occurred: ${error}`);
}}
fetchDataAsync();
When to Use Promises?
Promises are suitable when:
- You’re dealing with multiple async operations.
- You want to improve readability by avoiding callback hell.
- Managing dependencies between tasks is required.
Conclusion
Promises are a cornerstone of modern JavaScript, enabling powerful, clean handling of asynchronous code. By mastering promises, you can write more reliable and maintainable applications.
Powered by Froala Editor