While Promise Chaining is great for running tasks one after another, Promise.all() is used when you want to run multiple asynchronous tasks at the same time (in parallel) and wait for all of them to finish.
1. Basic Syntax
Promise.all() takes an array of promises as input and returns a single Promise.
- If all resolve: It returns an array of the results in the exact same order as the input.
- If any one fails: The entire Promise.all() immediately rejects with that error.
JavaScript
const p1 = Promise.resolve("Data from API 1");
const p2 = new Promise((resolve) => setTimeout(() => resolve("Data from API 2"), 2000));
const p3 = fetch("https://jsonplaceholder.typicode.com/posts/1").then(res => res.json());
Promise.all([p1, p2, p3])
.then((results) => {
console.log(results[0]); // "Data from API 1"
console.log(results[1]); // "Data from API 2"
console.log(results[2]); // { userId: 1, id: 1, title: ... }
})
.catch((error) => {
console.error("One of the promises failed!", error);
});
2. Basic Example
Imagine you need to fetch a user’s profile and their photo gallery simultaneously to save time.
JavaScript
const fetchProfile = new Promise(resolve => setTimeout(() => resolve("Profile Data"), 1000));
const fetchPhotos = new Promise(resolve => setTimeout(() => resolve(["Photo1", "Photo2"]), 2000));
Promise.all([fetchProfile, fetchPhotos])
.then((results) => {
// results is an array: [resultOfPromise1, resultOfPromise2]
const [profile, photos] = results;
console.log(profile); // "Profile Data"
console.log(photos); // ["Photo1", "Photo2"]
})
.catch(error => {
console.error("One of the requests failed:", error);
});
3. The “All or Nothing” Rule
The most important thing to remember is that Promise.all is atomic. If you have 10 promises and 9 succeed but 1 fails, you get nothing back except the error.
JavaScript
const p1 = Promise.resolve("A");
const p2 = Promise.reject("Error in B!");
const p3 = Promise.resolve("C");
Promise.all([p1, p2, p3])
.then(values => console.log(values))
.catch(err => console.log("Caught:", err));
// Output: Caught: Error in B!
// Even though p1 and p3 were successful, the entire operation failed.
4. Why use Promise.all()?
A. Performance (Concurrency)
If you have three API calls that each take 1 second:
- Chaining them (serial) will take 3 seconds.
- Promise.all (parallel) will take only 1 second.
B. Cleaning up Async/Await
You can use await with Promise.all for very clean, readable code:
JavaScript
async function fetchAllData() {
try {
const [users, posts, settings] = await Promise.all([
fetch('/api/users'),
fetch('/api/posts'),
fetch('/api/settings')
]);
// Process all data here
} catch (error) {
console.error("Failed to load dashboard", error);
}
}
5. Real-World Use Case: Multiple API Calls
If you are building a dashboard that shows weather, news, and stock prices, you shouldn’t wait for the weather to finish before starting the news. You trigger them all at once.
async function getDashboardData() {
try {
const [weather, news, stocks] = await Promise.all([
fetch('/api/weather').then(r => r.json()),
fetch('/api/news').then(r => r.json()),
fetch('/api/stocks').then(r => r.json())
]);
console.log("Dashboard loaded", { weather, news, stocks });
} catch (err) {
console.error("Could not load dashboard:", err);
}
}
