JavaScript Promises, Explained Through a Guy Trying to Go Viral

Raju Rastogi is a fourth-year CS student. Decent coder, five GitHub repos, two of which are "Hello World" in different languages. His mother has been dreaming of the day he walks in with a FAANG offer letter so they can finally stop eating bhindi every day.
Somewhere between his third LeetCode session of the week, Raju discovered something he believes matters more than DSA practice: Aura Farming.
He wants to top the algorithm. So he posts "Just solved a LeetCode problem at 2AM" on X. He shares a video of his aesthetic setup, showing he shipped a full-stack app in 7 hours. He hits post.
And then... he waits.
Does the world stop? Does he sit there staring at the screen for the next eight hours? No. He sleeps. He eats. Life moves on. The post is out there doing its thing in the background.
That post is a JavaScript Promise. Here is how they work.
What is a Promise?
A Promise is an object that represents the eventual result of an asynchronous operation. It does not give you the result immediately. It says: "I will get back to you on this."
Raju's post works the same way. Either it blows up, or it gets two likes from his maa and his sister Kammo.
A Promise exists in one of three states:
Pending: the operation is in progress. The post is up, but Raju has no idea what is happening yet.
Fulfilled: it worked. The post went viral. Engagement is through the roof. Aura is up.
Rejected: it failed. No engagement. Just Kammo dropping a thumbs up emoji out of pity. Major L.
// Raju posts his video on X
const postReel = new Promise((resolve, reject) => {
// The algorithm runs — this is your async operation
const views = getViewsFromX();
if (views > 1000) {
resolve("Post gone viral. Aura ++"); // fulfilled
} else {
reject("2 likes. Cooked."); // rejected
}
});
When you create a Promise, you pass it a function with two parameters: resolve and reject. Call resolve when things go well. Call reject when they do not. The Promise object then carries that outcome forward for you to handle later.
.then() and .catch() Handle the Outcome
After posting, Raju does not freeze. He already has a plan for both outcomes:
Goes viral: he retweets, thanks everyone, farms more aura.
Zero engagement: he deletes the post. Acts like it never happened. Nobody needs to know.
In JavaScript, these two scenarios map directly to:
.then()runs when the Promise is fulfilled.catch()runs when it is rejected
postReel
.then((message) => {
// Post went viral
console.log(message);
postFollowUp("Thanks for the love! More content coming!");
})
.catch((error) => {
// Post tanked
console.log(error);
deletePost();
openLeetCode(); // back to basics
});
// Meanwhile, Raju is already asleep
console.log("Raju is sleeping, eating, and praying.");
That last console.log runs before either .then() or .catch() gets a chance to fire. This is what non-blocking means in practice. JavaScript does not sit around waiting for the Promise to settle. It keeps moving to the next line of code while the async operation runs in the background. The .then() or .catch() callback only gets called once the Promise resolves or rejects.
Promise Chaining: One Win Leads to the Next
If the post does well, Raju is not stopping there. He has a full content roadmap mapped out in his head:
Post goes viral on X, retweet with gratitude, drop an X thread, post reels on Instagram, publish a humble-brag on LinkedIn about his "journey."
Every step only makes sense if the previous one succeeded. This is Promise Chaining. Each .then() receives the output of the step before it.
postReel("Full stack app in 7 hours")
.then((views) => {
// X post blew up — now drop the thread
return postTwitterThread("How I built it!");
})
.then((twitterEngagement) => {
// Thread worked — time for LinkedIn
return postLinkedIn("Grateful for this journey. #OpenToWork");
})
.then((linkedinReactions) => {
// Recruiter DMs incoming
console.log("Aura maxed out.");
return acceptJobOffer();
})
.catch((err) => {
// Any step in the chain can fail and land here
console.log("Roadmap flopped. Back to DSA.", err);
});
The .catch() at the bottom covers the entire chain. If anything fails at any step, it lands there. You do not need a separate .catch() after every .then().
Promise Methods: When Multiple Things Run at Once
Raju is not limiting himself to one platform. He is going wide. Instagram, X, LinkedIn, all at once. JavaScript has four built-in methods for handling multiple Promises running in parallel, and each one behaves differently.
Promise.all()
Raju needs all three platforms to deliver. If Instagram flops, the whole strategy falls apart.
Promise.all() takes an array of Promises and returns a single Promise that only resolves if every Promise in the array resolves. If one rejects, the whole thing rejects.
Promise.all([
postInstagram("Reel of the grind"),
postX("Thread about the project"),
postLinkedIn("Big announcement"),
])
.then(([igViews, xRT, linkedinReacts]) => {
console.log("Stonks.");
})
.catch((err) => {
console.log("One platform tanked everything.", err);
});
Use this when you genuinely need all operations to succeed before moving forward.
Promise.allSettled()
Raju has come around to setting realistic expectations. He wants to see what happened on every platform, regardless of outcome. One bad result should not hide the others.
Promise.allSettled() runs through every Promise and waits for all of them to settle, whether they resolve or reject. It returns an array of objects, each with a status of either "fulfilled" or "rejected", along with the value or reason.
Promise.allSettled([
postInstagram(),
postX(),
postLinkedIn(),
]).then((results) => {
results.forEach((result, i) => {
if (result.status === "fulfilled") {
console.log(`Platform \({i}: +\){result.value} views`);
} else {
console.log(`Platform \({i}: flopped — \){result.reason}`);
}
});
});
Use this when you need a full picture of what happened and do not want a single failure to hide the rest of the results.
Promise.race()
Raju does not care about the final score. He wants to know which platform responds first, win or loss, because that determines where he puts his energy next.
Promise.race() returns a Promise that resolves or rejects with the result of whichever Promise settles first. The others are ignored once the first one comes in.
Promise.race([
postInstagram(),
postX(),
postLinkedIn(),
])
.then((firstResult) => {
console.log("First platform in:", firstResult);
// Double down on whichever one moved first
})
.catch((err) => {
console.log("First response was bad.", err);
});
Use this for timeout patterns or when the fastest response is the only one that matters.
Promise.any()
Placement season is here and Raju is not in the mood to be picky. Instagram and X can tank. He just needs LinkedIn to come through. One win is enough.
Promise.any() resolves as soon as at least one Promise in the array resolves. It only rejects if every single Promise rejects, and it tells you all the reasons why via an AggregateError.
Promise.any([
postInstagram(), // L
postX(), // L
postLinkedIn(), // recruiter DM
])
.then((win) => {
console.log("One is enough.", win);
})
.catch((err) => {
// Only fires if ALL three failed
console.log("Everything flopped.", err);
});
Use this when any single success is a valid outcome and you do not need all of them to deliver.
A Quick Comparison
| Method | Resolves when | Rejects when |
|---|---|---|
Promise.all() |
All resolve | Any one rejects |
Promise.allSettled() |
All settle (no rejection) | Never rejects |
Promise.race() |
First one settles | First one rejects |
Promise.any() |
First one resolves | All reject |
Conclusion
Raju got placed. The bhindi era is finally over.
Promises are not as complicated as they look once you see the pattern. An operation starts. You do not wait around for it. When it finishes, either .then() runs because it worked, or .catch() runs because it did not. The rest of your code keeps moving while all of that is happening.
Once you get comfortable with that idea, chaining and the parallel methods start to feel natural. You are just describing what should happen next, and what to do if something goes wrong along the way.
You already live this every day. The Zomato order you placed. The exam result you are waiting on. The friend who said he will return the money. All of them are pending Promises with two possible outcomes.
To recap:
A Promise is pending until the async task finishes. It either resolves (success, handled by .then()) or rejects (failure, handled by .catch()). And while it is working, JavaScript does not wait.
At the end of the day, Aal Iz Well !




