Life, Commitments, and JavaScript Promises
Turns out your life already understands async programming

Life is full of promises. We make them to ourselves and to other people almost every day. We say things like, “I’ll start exercising from tomorrow,” or “We’ll definitely go on a trip this weekend.” At work, we promise, “I’ll submit the project by Friday.”
Some promises are kept. Some are broken. And some stay in that unclear stage where nothing really happens and everyone is just waiting.
JavaScript Promises work in a very similar way. They wait for something to happen. While waiting, nothing is final. In the end, they either succeed or fail. That is why promises in JavaScript are easier to understand when you connect them to real life.
New Year’s Promise: I Will Exercise
At the start of the year, I promise myself that I will exercise every day. In the beginning, motivation feels strong. I plan workouts and think this time it will work.
At this point, the promise is not completed. I am still waiting to see if I actually exercise or not.
If I exercise regularly, the promise is kept.
If I stop after a few days, the promise is broken.
const exercisePromise = new Promise((resolve, reject) => {
const exercisedToday = true;
if (exercisedToday) {
resolve("I kept my exercise promise");
} else {
reject("I skipped the workout");
}
});
exercisePromise
.then(result => console.log(result))
.catch(error => console.log(error));
Explanation:-
First, I create a new Promise. As soon as the Promise is created, it is in the pending state.
Inside the Promise, I check a condition. Here, exercisedToday decides the result.
If the condition is true, I call resolve(). This means the promise is fulfilled.
If the condition is false, I call reject(). This means the promise is broken.
The then() block runs when the promise is fulfilled.
The catch() block runs when the promise is rejected.
Weekend Trip with Friends
We plan a weekend trip with friends. Someone sends a message in the group chat saying, “Let’s go this weekend.” Everyone replies with excitement. For now, it feels like the trip is happening.
But nothing is final yet.
One friend says they need to check their schedule. Another says they will confirm later. We are stuck waiting. The plan is not successful and not canceled either. It is just waiting for everyone’s answer.
This waiting phase is exactly what a Promise represents in JavaScript.If all friends finally say yes, the trip happens and everyone is happy.If even one friend cancels at the last moment, the whole plan usually falls apart.
const weekendTrip = new Promise((resolve, reject) => {
const allFriendsConfirmed = false;
if (allFriendsConfirmed) {
resolve("The trip is confirmed");
} else {
reject("The trip was canceled");
}
});
weekendTrip
.then(message => console.log(message))
.catch(reason => console.log(reason));
Let's understand this example step by step
First, we create a new Promise using new Promise().
We do this because the result of the trip is not known yet. We are waiting for something to happen in the future. That is exactly when Promises are used in JavaScript.
Inside the Promise, JavaScript gives us two tools:
resolvereject
Think of resolve as saying, “Yes, it worked.”
Think of reject as saying, “No, it failed.”
At the moment the Promise is created, it is automatically in the pending state. This matches the real-life situation where we are waiting for friends to confirm.
The variable allFriendsConfirmed represents the final decision of the group. In real life, this would be replies in the group chat.
If allFriendsConfirmed is true, we call resolve(). This means the Promise is successful and the trip is confirmed.
If allFriendsConfirmed is false, we call reject(). This means the Promise fails and the trip is canceled.
Outside the Promise, we use .then() and .catch().
The .then() block runs only if the Promise is resolved. This is where we handle success, like booking tickets or packing bags.
The .catch() block runs only if the Promise is rejected. This is where we handle failure, like sending a message saying the plan is canceled.
JavaScript Promise Methods
Now that we know how promish work lets go through each promish methords starting with then
.then() – When a Promise Goes Right
I promise myself I will finish my work early.
If I actually finish it, I feel relaxed and plan something fun.
This “what I do after success” is exactly what .then() is.
const workPromise = new Promise((resolve, reject) => {
const workDone = true;
if (workDone) {
resolve("Work finished");
} else {
reject("Work not finished");
}
});
workPromise.then(result => {
console.log(result);
console.log("Now I can relax");
});
Explanation
.then() runs only when the promise is resolved. It handles the happy path. We use it to decide what happens next
If the promise fails, then () is skipped.
.catch() – When a Promise Fails
manly catch is like then method, but it is used when a promise is rejected, " like when we all got rejected in some places (you know what I mean)."
workPromise.catch(error => {
console.log(error);
console.log("I need a backup plan");
});
Explanation
.catch() runs only when the promise is rejected. It handles errors and failures. Without it, errors stay unhandled
Think of .catch() as damage control.
.finally() – Happens No Matter What
It's like taking an exam, knowing that the results will be released whether we pass or fail.
workPromise
.then(result => console.log(result))
.catch(error => console.log(error))
.finally(() => {
console.log("Status update sent");
});
Explanation
.finally() runs after resolve or reject. It does not care about the result. Used for cleanup, logs, reports
Promise.all() – All Must Succeed
We plan a trip.
Tickets, hotel, and leave must all be confirmed.
If one thing fails, the trip fails.
Promise.all([
bookTickets(),
bookHotel(),
getLeave()
])
.then(() => {
console.log("Trip is fully planned");
})
.catch(() => {
console.log("Trip canceled");
});
Explanation
Waits for all promises to resolve. If one rejects, everything fails. Used when everything is required
Promise.allSettled()
Imagine applying for several jobs at the same time. I send my resume to different companies, and then I wait. I already know what usually happens in these situations. Some companies reply with good news. Some reply with a rejection. Some never reply at all. None of this is surprising. At this point, I am not thinking about success or failure. I just want to understand the overall situation.
After a few days or weeks, I want a clear picture. I want to know which companies replied, what they replied with, and which ones stayed silent. I am not stopping just because one company rejected me. I am also not stopping just because one company said yes. I want the full report. That way, I can decide my next step calmly.
This exact thinking is what Promise.allSettled() is represented in JavaScript.
In JavaScript, we use Promise.allSettled() When we start multiple tasks at the same time, and we want to wait until all of them are finished. The important part is that it does not matter whether those tasks succeed or fail. The method waits patiently until every promise has either resolved or rejected.
Here is how it looks in code.
const jobApplications = Promise.allSettled([
applyCompanyA(),
applyCompanyB(),
applyCompanyC()
]);
jobApplications.then(results => {
console.log(results);
});
In this code, each function represents one job application. Some of these promises may be resolved, meaning the company responded positively. Some may reject, meaning the company responded negatively or something went wrong. Promise.allSettled() does not react immediately to any of this. It simply waits until every single promise is done.
Only after all promises are fulfilled does it move forward and return the result. That result is always an array. Each item in the array represents the final state of one promise.
The result looks something like this.
[
{ status: "fulfilled", value: "Offer from Company A" },
{ status: "rejected", reason: "Rejected by Company B" },
{ status: "fulfilled", value: "Interview call from Company C" }
]
Each object tells a complete story. If the status is "fulfilled," the promise succeeded, and the result is in the value field. If the status is "rejected," the promise failed, and the reason explains why. Nothing is hidden or skipped. Every promise has a final outcome. Promise.allSettled() is special because it doesn't stop early if something fails. It doesn't throw an error automatically or decide what success or failure means for everything. It just reports the facts. This is useful in many real situations. When failure is normal and expected, and when we need a full overview instead of a quick answer, Promise.allSettled() is the right choice. Think of it like checking all your job applications at once. You're not judging yourself on one reply. You're just gathering information to decide what to do next.
Promise.race() – Whoever Finishes First
I order food from two apps at the same time because I'm hungry and don't want to wait. I'm not being fair or comparing quality. I just eat the food that arrives first. As soon as one delivery person arrives, my wait is over. I don't care if the other delivery is still coming or gets canceled. The first one to arrive decides everything. This is how Promise.race() works in JavaScript. With Promise.race(), we give it several promises and tell JavaScript to wait. But here's the key: JavaScript only waits for the first one to finish. The first promise can succeed or fail. Whatever happens first is the final result.
Here is how it looks in code.
Promise.race([
zomatoOrder(),
swiggyOrder()
])
.then(result => {
console.log("First result:", result);
})
.catch(error => {
console.log("First failure:", error);
});
In this example, both orders start at the same time. JavaScript doesn't know which will finish first. As soon as one promise resolves, the .then() block runs. If the first promise rejects, the .catch() block runs instead. The main point is that speed is what counts. Once the first promise finishes, whether it succeeds or fails, the race ends. The other promises are ignored. This method is useful when speed is more important than the result. It's often used for timeouts, picking the fastest server, or getting the quickest response. An easy way to remember Promise.race() is: Whoever finishes first decides for everyone.
Promise.any() – I Need One Success
Imagine applying to many companies at once. I expect rejections, and that's okay. My goal is to get just one offer. It doesn't matter which company or how many rejections come first. Once I get an offer, I can stop searching. This is how Promise.any() works. In JavaScript, Promise.any() waits for several promises but only cares about success. As soon as one promise succeeds, the operation is complete.
Promise.any([
interviewCompanyA(),
interviewCompanyB(),
interviewCompanyC()
])
.then(result => {
console.log("Got one success:", result);
})
.catch(error => {
console.log("All promises failed");
});
In this example, all interviews start at the same time. Some may reject quickly, while others take longer. JavaScript waits as long as there's hope for one success. Once a promise resolves, the .then() block runs, and other results don't matter. The .catch() block runs only if every promise is rejected, meaning no company said yes. This is different from Promise.race(). In a race, the first result wins even if it's a failure. In Promise.any(), failures are ignored if there's still a chance of success. Think of Promise.any() like this: Failures don't matter. One success is enough.
Conclusion
Promises in JavaScript are familiar concepts. We make plans, wait for results, and react based on outcomes. Sometimes things go well, sometimes they don't, and sometimes we need the whole picture before deciding. A basic Promise shows how JavaScript waits. It starts as pending, then becomes fulfilled if successful, or rejected if not. Methods like .then() and .catch() help us decide what to do next, while .finally() ensures some actions happen regardless of the outcome. With multiple promises, JavaScript offers different tools. Promise.all() expects all to succeed. Promise.allSettled() reports each task's result. Promise.race() focuses on the first result. Promise.any() waits for at least one success. When we relate these to real life, Promises become clear. They model waiting, decisions, and outcomes in code. Understanding Promises is more than syntax; it's about how JavaScript handles time, results, and flow. Once understood, asynchronous code feels natural.




