?? Mastering JavaScript Promises: Understanding Promise vs. Promise.all()
Rakesh Pathania
Building @DigiMantra Labs ??|| Backend Developer || Node.js || Express || Fastify || NestJs || Laravel || PHP || GIT || React.js || Vue.js || MongoDb || MySQL || PostgresSQL || GraphQL
JavaScript's asynchronous behavior is powered by Promises ?, making it easier to handle API calls, database queries, and microservices efficiently. But when should you use a single Promise, and when is Promise.all() the better choice? Let's break it down with real-world examples. ??
Understanding Promises in JavaScript ??
A Promise is an object representing an asynchronous operation that may:
Example: A Single Promise ?
const fetchUser = new Promise((resolve, reject) => {
setTimeout(() => resolve("User data fetched!"), 2000);
});
fetchUser.then(data => console.log(data));
console.log("Fetching user...");
Output: ???
Fetching user...
(User data appears after 2 seconds)
User data fetched!
?? Key Takeaway: A single promise handles one asynchronous task.
Understanding Callbacks, Promises, and Async/Await ??
JavaScript provides multiple ways to handle asynchronous operations:
1. Callbacks (Older Approach) ??
function fetchData(callback) {
setTimeout(() => {
callback("Data fetched");
}, 2000);
}
fetchData(data => console.log(data));
?? Problem: Callbacks can lead to callback hell ??, making code harder to read and maintain.
2. Promises (Modern Approach) ??
function fetchData() {
return new Promise(resolve => {
setTimeout(() => resolve("Data fetched"), 2000);
});
}
fetchData().then(data => console.log(data));
? Benefit: Avoids callback hell, making code more readable. ??
3. Async/Await (More Readable & Modern) ??
async function fetchData() {
return new Promise(resolve => {
setTimeout(() => resolve("Data fetched"), 2000);
});
}
(async () => {
const data = await fetchData();
console.log(data);
})();
? Benefit: Code looks synchronous and is easier to manage. ??
Why Use Promise.all()? ?
If you need to execute multiple asynchronous operations in parallel and wait for all of them to finish, Promise.all() is the best approach. It runs all promises at the same time and returns an array of results once all are resolved. ??
领英推荐
Example: Fetching Multiple APIs in Parallel ??
async function fetchData() {
try {
const userPromise = fetch("https://api.example.com/user").then(res => res.json());
const ordersPromise = fetch("https://api.example.com/orders").then(res => res.json());
const notificationsPromise = fetch("https://api.example.com/notifications").then(res => res.json());
const [user, orders, notifications] = await Promise.all([userPromise, ordersPromise, notificationsPromise]);
console.log("User Data:", user);
console.log("Orders:", orders);
console.log("Notifications:", notifications);
} catch (error) {
console.log("Error fetching data:", error);
}
}
fetchData();
Why is Promise.all() Better Here?
? Faster Execution: Instead of waiting for each API call sequentially, all requests happen simultaneously. ? ? Efficiency: Reduces total wait time for the user. ?
What Happens If One Promise Fails? ?
A downside of Promise.all() is that if any promise fails, the entire operation fails. ??
Example: Handling Failures in Promise.all() ??
const promise1 = new Promise(resolve => setTimeout(() => resolve("Success 1"), 2000));
const promise2 = new Promise((_, reject) => setTimeout(() => reject("Error in Promise 2"), 1000));
const promise3 = new Promise(resolve => setTimeout(() => resolve("Success 3"), 3000));
Promise.all([promise1, promise2, promise3])
.then(results => console.log("All resolved:", results))
.catch(error => console.log("Error:", error));
Output: ???
Error: Error in Promise 2
?? Takeaway: One failure cancels everything! ??
Using Promise.allSettled() for Handling Partial Failures ?
If you want all promises to run regardless of failures, use Promise.allSettled(). This ensures that even if some promises fail, you still get the results of the others. ??
const promises = [
fetch("https://api.example.com/user").then(res => res.json()),
fetch("https://api.example.com/orders").then(res => res.json()),
fetch("https://api.example.com/notifications").then(res => res.json()),
fetch("https://api.example.com/wrong-url").then(res => res.json()) // ? This will fail!
];
Promise.allSettled(promises).then(results => {
results.forEach((result, index) => {
if (result.status === "fulfilled") {
console.log(`Promise ${index + 1} succeeded:`, result.value);
} else {
console.log(`Promise ${index + 1} failed:`, result.reason);
}
});
});
? Best use case: When you need some results even if others fail, like loading widgets on a dashboard. ??
Final Thoughts ??
By mastering these techniques, you can write more efficient and robust asynchronous JavaScript. ???
Do you use Promise.all() in your projects? Let me know in the comments! ??