Promise APIs + Interview Questions and all, allSettled, race, any in javascript
Promise APIs in JavaScript - all, allSettled, race, any
Hey everyone! Welcome back to Namaste JavaScript. Today we are going to cover Promise APIs. There are four promise APIs which are majorly important and I will cover all of them in this blog.
These Promise APIs will be very helpful when you are giving interviews and also when building real-world applications. I was building a major project and had to make parallel API calls - that's where these Promise APIs came into picture!
Let's cover all four:
- Promise.all
- Promise.allSettled
- Promise.race
- Promise.any
Important Terminology First!
Before we start, let's understand the lingo used in Promise world:
- Settled = Got the result (can be success OR failure)
- Fulfilled / Resolved = Success
- Rejected = Failure
Remember: Settled doesn't mean success - it means the promise has completed (either way)!
1. Promise.all
Used when you want to make parallel API calls and get all results together.
Contract:
- Takes an array of promises as input
- Returns an array of all results
- Waits for ALL promises to finish
- Fail Fast: If ANY promise fails, it immediately returns error
Success Case:
const p1 = new Promise((resolve, reject) => {
setTimeout(() => resolve("P1 Success"), 3000);
});
const p2 = new Promise((resolve, reject) => {
setTimeout(() => resolve("P2 Success"), 1000);
});
const p3 = new Promise((resolve, reject) => {
setTimeout(() => resolve("P3 Success"), 2000);
});
Promise.all([p1, p2, p3])
.then((results) => {
console.log(results);
})
.catch((err) => {
console.error(err);
});
OUTPUT: (after 3 seconds) ["P1 Success", "P2 Success", "P3 Success"]
It waited for ALL 3 promises (3 seconds for the longest one) and returned all results in an array!
Failure Case - Fail Fast:
const p1 = new Promise((resolve, reject) => {
setTimeout(() => resolve("P1 Success"), 3000);
});
const p2 = new Promise((resolve, reject) => {
setTimeout(() => reject("P2 Fail"), 1000); // This fails!
});
const p3 = new Promise((resolve, reject) => {
setTimeout(() => resolve("P3 Success"), 2000);
});
Promise.all([p1, p2, p3])
.then((results) => {
console.log(results);
})
.catch((err) => {
console.error(err);
});
OUTPUT: (after 1 second - NOT 3 seconds!) P2 Fail
Key Point: As soon as P2 failed (after 1 second), Promise.all immediately threw error. It did NOT wait for P1 and P3!
This is called FAIL FAST - if any one fails, return error immediately.
2. Promise.allSettled
What if you want results from successful promises even if some fail? Use Promise.allSettled!
Contract:
- Waits for ALL promises to settle (success OR failure)
- Returns array of objects with status and value/reason
- Never fails early - always waits for everyone
- SAFEST option among all Promise APIs!
const p1 = new Promise((resolve, reject) => {
setTimeout(() => resolve("P1 Success"), 3000);
});
const p2 = new Promise((resolve, reject) => {
setTimeout(() => reject("P2 Fail"), 1000);
});
const p3 = new Promise((resolve, reject) => {
setTimeout(() => resolve("P3 Success"), 2000);
});
Promise.allSettled([p1, p2, p3])
.then((results) => {
console.log(results);
})
.catch((err) => {
console.error(err);
});
OUTPUT: (after 3 seconds - waits for ALL)
[
{ status: "fulfilled", value: "P1 Success" },
{ status: "rejected", reason: "P2 Fail" },
{ status: "fulfilled", value: "P3 Success" }
]
Key Points:
- It waited for all 3 promises (3 seconds)
- Returns array of OBJECTS (not just values!)
- Success:
{ status: "fulfilled", value: "..." } - Failure:
{ status: "rejected", reason: "..." }
Use Case: Showing 5 cards on page from 5 API calls - if one fails, still show 4 cards!
3. Promise.race
As the name suggests - it's a RACE! First one to finish wins.
Contract:
- Returns result of FIRST SETTLED promise
- Doesn't matter if it's success or failure
- First to finish = Winner
Success Case:
const p1 = new Promise((resolve, reject) => {
setTimeout(() => resolve("P1 Success"), 3000);
});
const p2 = new Promise((resolve, reject) => {
setTimeout(() => resolve("P2 Success"), 1000); // Fastest!
});
const p3 = new Promise((resolve, reject) => {
setTimeout(() => resolve("P3 Success"), 2000);
});
Promise.race([p1, p2, p3])
.then((result) => {
console.log(result);
})
.catch((err) => {
console.error(err);
});
OUTPUT: (after 1 second) P2 Success
P2 finished first (1 second), so we got P2's result. It did NOT wait for others!
Failure Case:
const p1 = new Promise((resolve, reject) => {
setTimeout(() => resolve("P1 Success"), 3000);
});
const p2 = new Promise((resolve, reject) => {
setTimeout(() => resolve("P2 Success"), 5000);
});
const p3 = new Promise((resolve, reject) => {
setTimeout(() => reject("P3 Fail"), 2000); // Fastest but fails!
});
Promise.race([p1, p2, p3])
.then((result) => {
console.log(result);
})
.catch((err) => {
console.error(err);
});
OUTPUT: (after 2 seconds) P3 Fail
P3 finished first (2 seconds) but it FAILED - so we get the error! Race doesn't care about success/failure, only speed!
Interview Answer: Promise.race returns the result of the first SETTLED promise, whether it's success or failure.
4. Promise.any
Similar to race, but it's SUCCESS SEEKING! It waits for the first SUCCESS.
Contract:
- Returns result of FIRST SUCCESSFUL promise
- Ignores failures, keeps waiting for success
- If ALL fail, returns AggregateError
Success Case:
const p1 = new Promise((resolve, reject) => {
setTimeout(() => resolve("P1 Success"), 3000);
});
const p2 = new Promise((resolve, reject) => {
setTimeout(() => reject("P2 Fail"), 1000); // Fails
});
const p3 = new Promise((resolve, reject) => {
setTimeout(() => reject("P3 Fail"), 2000); // Fails
});
Promise.any([p1, p2, p3])
.then((result) => {
console.log(result);
})
.catch((err) => {
console.error(err);
});
OUTPUT: (after 3 seconds) P1 Success
P2 failed at 1 second - IGNORED!
P3 failed at 2 seconds - IGNORED!
P1 succeeded at 3 seconds - RETURNED!
Promise.any kept waiting for a success!
All Fail Case - AggregateError:
const p1 = new Promise((resolve, reject) => {
setTimeout(() => reject("P1 Fail"), 3000);
});
const p2 = new Promise((resolve, reject) => {
setTimeout(() => reject("P2 Fail"), 1000);
});
const p3 = new Promise((resolve, reject) => {
setTimeout(() => reject("P3 Fail"), 2000);
});
Promise.any([p1, p2, p3])
.then((result) => {
console.log(result);
})
.catch((err) => {
console.error(err);
console.log(err.errors); // Array of all errors!
});
OUTPUT: (after 3 seconds - waits for all to fail) AggregateError: All promises were rejected ["P1 Fail", "P2 Fail", "P3 Fail"]
Key Point: When ALL promises fail, Promise.any returns an AggregateError with an errors array containing all the errors!
Quick Comparison Table
| API | What it returns | On Failure |
|---|---|---|
| Promise.all | Array of all values | Fail Fast - returns first error immediately |
| Promise.allSettled | Array of objects with status | Never fails - returns all results |
| Promise.race | First settled value (success/failure) | Returns error if first to settle fails |
| Promise.any | First successful value | AggregateError if ALL fail |
Interview Tips - How to Explain
Promise.all:
"Promise.all takes an array of promises and waits for ALL of them to fulfill. It returns an array of all results. But if ANY one promise gets rejected, it immediately returns that error - this is called fail fast behavior."
Promise.allSettled:
"Promise.allSettled waits for ALL promises to settle - whether they fulfill or reject. It returns an array of objects with status (fulfilled/rejected) and value/reason. It's the safest option as it never fails early."
Promise.race:
"Promise.race returns the result of the first SETTLED promise - whether it's success or failure. It's like a race - whoever finishes first wins, regardless of the outcome."
Promise.any:
"Promise.any is a success-seeking race. It returns the first SUCCESSFUL promise and ignores failures. If ALL promises fail, it returns an AggregateError containing all the errors."
Quick Recap
// Promise.all - All success or fail fast
Promise.all([p1, p2, p3])
// Returns: [val1, val2, val3] or first error
// Promise.allSettled - Wait for everyone
Promise.allSettled([p1, p2, p3])
// Returns: [{status, value/reason}, ...]
// Promise.race - First to finish
Promise.race([p1, p2, p3])
// Returns: first settled result (success or error)
// Promise.any - First success
Promise.any([p1, p2, p3])
// Returns: first success or AggregateError
OUTPUT Summary:
Promise.all -> [val1, val2, val3] OR Error
Promise.allSettled -> [{status, value}, {status, reason}, ...]
Promise.race -> val (first settled)
Promise.any -> val (first success) OR AggregateError
When to Use What?
- Promise.all - When you need ALL results and can't proceed if any fails
- Promise.allSettled - When you want all results regardless of failures (safest!)
- Promise.race - When you only care about the fastest response
- Promise.any - When you need the first successful response
Keep coding, keep learning!
Post a Comment