Promise Methods with real life analogy

Hello readers, If you are reading this blog, I assume you know about promises and how they work. But do you know that promises also offer methods to handle multiple promises? In this blog, I'm going to explain those methods with real-life analogies.
If you don't know promises, don't worry; I have provided a brief overview of them.
Topic Covered
Overview of Promise
Promise.all()
Promise.any()
Promise.allSettled()
Promise.race()
Overview of Promise
A Promise in JavaScript represents a value that will be available in the future.
Think of it like this:
When you order food online, you don’t get it instantly.
You get a confirmation that your order is being prepared.
Later, one of two things happens:
The food is delivered successfully
The order gets cancelled
That “future result” — whether success or failure — is exactly what a Promise represents.
A Promise Has 3 States
Pending – The task is still in progress.
Fulfilled – The task completed successfully.
Rejected – The task failed.
Once a Promise is fulfilled or rejected, it is permanently settled and cannot change.
And What About Multiple Promises?
In real applications, we rarely deal with just one async task.
We often need to:
Wait for multiple tasks to complete
Use the first successful result
React to whichever finishes first
Collect all results together
That’s where Promise combinator methods like:
Promise.allPromise.anyPromise.racePromise.allSettled
come into play.
And that’s exactly what this blog focuses on.
Let's start
Nowadays, many weddings are taking place, so I think this would be the best example to understand these methods. Suppose the preparation for a wedding is underway. To make the wedding a success, here are the things we need:
Caterer
Decorator
Venue (Hall)
DJ
Photographer
Promise.all()
To ensure the wedding is successful, you spoke to each of them, and all promised they would come. If anyone fails to fulfill their promise, you will face a lot of embarrassment. So, all are very important. For this, we use Promise.all(), which takes all the important promises to be fulfilled as an array. If any are rejected, it will show an error.
const caterer = Promise.resolve("Caterer confirmed");
const decorator = Promise.resolve("Decorator confirmed");
const hall = Promise.resolve("Hall confirmed");
const dj = Promise.reject("DJ not available");
const photographer = Promise.reject("Photographer is not available");
Promise.all([caterer, decorator, hall, dj,photographer])
.then((res) => {
console.log("All confirmed:", res);
})
.catch((err) => {
console.log("Cannot finalize booking:", err);
});
output -> cannot finalize bookign: DJ not available
So, when you want all the promises to be fulfilled, you use Promise.all(). It only succeeds when all the promises are fulfilled; otherwise, it fails and goes to catch.
Promise.any()
Now that you know the DJ is unavailable, you will contact other DJ providers and request their services. However, there is a chance they might be busy too, so you will reach out to multiple DJ providers and confirm with any who accept the order. So, Promise.any() takes multiple promises and returns as soon as any promise is fulfilled.
const dj1 = Promise.reject("DJ1 busy");
const dj2 = Promise.reject("DJ2 busy");
const dj3 = Promise.resolve("DJ3 available");
const dj4 = Promise.reject("DJ4 busy");
Promise.any([dj1, dj2, dj3, dj4])
.then((res) => {
console.log("Booked:", res);
})
.catch((err) => {
console.log("No DJ available:", err);
});
Output -> Booked: DJ3 available
Promise.race()
To understand this method, suppose you urgently need to book a hall and have contacted multiple venues. Since it's urgent, you decide to confirm whichever hall responds first. So, Promise.race() returns the promise that resolves or rejects first, even if it is rejected.
const hallA = new Promise((resolve, reject) => {
setTimeout(() => reject("Hall A available"), 4000);
});
const hallB = new Promise((resolve, reject) => {
setTimeout(() => resolve("Hall B available"), 1000);
});
const hallC = new Promise((resolve, reject) => {
setTimeout(() => resolve("Hall C available"), 3000);
});
Promise.race([hallA, hallB, hallC])
.then((res) => {
console.log("First response:", res);
})
.catch((err) => {
console.log("First response:", err);
});
output-> First response: Hall B available
Promise.allSettled()
Now, you have booked all the services (Caterer, Decorator, Hall, DJ, Photographer) successfully, and the wedding is completed. The day after the wedding, a family meeting is happening, and you need all the reviews on who fulfilled their promise and who failed (rejected).
To get all this data, we use Promise.allSettled(). It returns all the promise results as an array.
Promise.allSettled([caterer, decorator, hall, dj])
.then((results) => {
console.log("Final Vendor Status:", results);
});
[
{ status: "fulfilled", value: "Caterer confirmed" },
{ status: "fulfilled", value: "Decorator confirmed" },
{ status: "fulfilled", value: "Hall confirmed" },
{ status: "rejected", reason: "DJ not available" },
{ status: "fulfilled", reason: "Photographer confirmed" }
]
This blog covers the Promise methods: all, any, allSettled, and race. I hope this analogy helps you understand the Promise methods well. Here is a mental map to remember the methods easily:
all - All promises should be fulfilled; otherwise, you will get an error.
any - If any one is fulfilled, then that will be returned.
race - Any promise that is fulfilled or rejected first will be returned.
allSettled - It will return all the promise statuses after resolving all.
Conclusion
JavaScript Promises are not just a syntax feature or an interview topic — they represent real-world coordination and decision-making.
Just like planning a wedding:
Sometimes you need everyone to confirm before moving forward (
Promise.all).Sometimes you just need one successful option to proceed (
Promise.any).Sometimes you react to whoever responds first, whether good or bad (
Promise.race).And sometimes you simply need a full report of what worked and what didn’t (
Promise.allSettled).
Each method serves a different purpose.
Using the wrong one can lead to unexpected behavior, unnecessary failures, or performance issues. Using the right one makes your asynchronous logic clean, predictable, and powerful.
And once you master async control, your confidence in building real-world applications — frontend or backend — increases significantly.
That’s the real power of Promises.
That's it for this blog, i will be back with another interesting blog. Bye





