Chapter 12 β Promises & Promise.all
π Definition
A Promise is an object representing the eventual completion or failure of an asynchronous operation, with three possible states: pending, fulfilled, rejected.
π Explanation
A Promise transitions exactly once: from pending β fulfilled (with a value) or pending β rejected (with a reason). Once settled, it can't change.
Handlers
.then(onFulfilled, onRejected)β register success/failure handlers..catch(fn)β short for.then(undefined, fn)..finally(fn)β always runs (cleanup).
Static Methods
| Method | Resolves when⦠| Rejects when⦠|
|---|---|---|
Promise.all |
all resolve | any rejects (fails fast) |
Promise.allSettled |
all settle (never rejects) | β |
Promise.race |
first settles (any outcome) | first settles (any outcome) |
Promise.any |
first fulfilled | all reject (AggregateError) |
π» Code Example β Creating a Promise
function wait(ms) {
return new Promise((resolve, reject) => {
if (ms < 0) return reject(new Error("Negative ms"));
setTimeout(resolve, ms);
});
}
wait(1000).then(() => console.log("1 second later"));π» Code Example β Chaining
fetchUser(1)
.then(user => fetchOrders(user.id))
.then(orders => orders.filter(o => o.status === "paid"))
.then(paid => console.log("Paid orders:", paid))
.catch(err => console.error("Something failed:", err))
.finally(() => console.log("Done"));Each .then returns a new Promise β the next handler receives whatever the previous one returned.
π» Code Example β async/await
async function loadDashboard(userId) {
try {
const user = await fetchUser(userId);
const orders = await fetchOrders(user.id);
return { user, orders };
} catch (err) {
console.error("Failed to load dashboard:", err);
throw err;
}
}β
asyncfunctions always return a Promise.awaitpauses inside the async function only, not the whole program.
π» Code Example β Promise.all (Parallel)
async function loadDashboard(userId) {
// All three start at the same time β total time β slowest one
const [user, orders, notifications] = await Promise.all([
fetchUser(userId),
fetchOrders(userId),
fetchNotifications(userId),
]);
return { user, orders, notifications };
}β οΈ Common Mistake β Sequential Awaits
// β Slow β takes the SUM of all three
const user = await fetchUser(id);
const orders = await fetchOrders(id);
const notifs = await fetchNotifications(id);
// β
Fast β takes the MAX of all three
const [user, orders, notifs] = await Promise.all([
fetchUser(id), fetchOrders(id), fetchNotifications(id),
]);π» Code Example β Promise.allSettled
const results = await Promise.allSettled([
fetchUser(1), // resolves
fetchUser(999), // rejects (not found)
fetchUser(2), // resolves
]);
results.forEach((r, i) => {
if (r.status === "fulfilled") console.log(i, "β", r.value);
else console.log(i, "β", r.reason);
});Use when you want all results, even if some fail.
π» Code Example β Promise.race
function timeout(ms) {
return new Promise((_, reject) =>
setTimeout(() => reject(new Error("Timeout")), ms)
);
}
await Promise.race([
fetch("/api/data"),
timeout(3000), // rejects after 3s
]);π» Code Example β Promise.any
// First successful CDN wins
await Promise.any([
fetch("https://cdn1.example.com/data"),
fetch("https://cdn2.example.com/data"),
fetch("https://cdn3.example.com/data"),
]);π» Code Example β Error Handling Strategies
// Strategy 1: catch on each call to not stop the batch
const results = await Promise.all(
ids.map(id =>
fetchUser(id).catch(err => ({ id, error: err.message }))
)
);
// Strategy 2: use allSettled
const settled = await Promise.allSettled(ids.map(fetchUser));π» Code Example β Microtask vs Macrotask
console.log("1");
setTimeout(() => console.log("2"), 0);
Promise.resolve().then(() => console.log("3"));
console.log("4");
// Output: 1, 4, 3, 2
// Promises (microtasks) run BEFORE setTimeout (macrotasks).For a visual, step-by-step explanation of why this happens, see Chapter 10 β Event Loop & Task Queues.
π Real-World Impact
- API parallelization in dashboards (
Promise.allsaves 60β80% of load time). - Retries with backoff use Promises chained recursively.
- Timeouts wrap fetches with
Promise.race.
π― Likely Interview Questions
- What is a Promise?
- Difference between
Promise.allandPromise.allSettled? - What is
async/await? Is it the same as Promises? β Sugar over Promises.asyncalways returns a Promise. - How do you handle one failing promise without killing the whole batch?
- Output prediction: see microtask example above.
β Array Methods | Index | Next: Event Loop & Task Queues β