🎢 JavaScript Promises: Your Trusty Delivery Robot
Imagine you have a robot helper that can go fetch things for you—like a pizza, a package, or a toy. But here’s the thing: the robot doesn’t bring it instantly. It promises to bring it back!
🤖 The Promise Delivery Robot
Think of a Promise like sending a robot on an errand:
- Robot leaves → Promise is pending (waiting)
- Robot returns with pizza → Promise is fulfilled (success! 🎉)
- Robot comes back empty → Promise is rejected (something went wrong 😢)
Your robot always comes back with one of two things: what you asked for, OR bad news.
📬 The .then() Method — “When You Get Back…”
The .then() method is like telling your robot:
“When you come back with the pizza, then put it on the table!”
fetchPizza()
.then(pizza => {
console.log("Yum! Got:", pizza);
});
How It Works:
- The robot (
fetchPizza()) goes to get pizza .then()waits patiently- When pizza arrives → your code runs!
Real Example:
// Robot fetches user data
fetch('/api/user')
.then(response => {
return response.json();
})
.then(userData => {
console.log("Hello,", userData.name);
});
💡 Key Point: .then() ONLY runs when things go right!
🚨 The .catch() Method — “If Something Goes Wrong…”
The .catch() method is your safety net. It’s like telling the robot:
“If you can’t find the pizza, catch the problem and tell me!”
fetchPizza()
.then(pizza => {
console.log("Got pizza!");
})
.catch(error => {
console.log("Oh no:", error);
});
Why It Matters:
- Pizza shop closed? →
.catch()handles it - Robot got lost? →
.catch()handles it - ANY problem →
.catch()is there!
// Real example with error handling
fetch('/api/secret-data')
.then(res => res.json())
.catch(err => {
console.log("Couldn't get data:", err);
showErrorMessage();
});
🧹 The .finally() Method — “No Matter What…”
The .finally() method runs always—success OR failure. Like telling your robot:
“Whether you bring pizza or not, finally close the door when you’re back!”
fetchPizza()
.then(pizza => console.log("Yay!"))
.catch(err => console.log("Boo!"))
.finally(() => {
console.log("Robot returned home");
hideLoadingSpinner();
});
Perfect For:
- ✅ Hiding loading spinners
- ✅ Cleaning up resources
- ✅ Logging that something finished
⛓️ Promise Chaining — Robot Relay Race!
What if you need the robot to do multiple errands in order?
That’s Promise Chaining! Each .then() passes its result to the next one, like a relay race.
graph TD A["Get User ID"] --> B["Fetch Profile"] B --> C["Load Posts"] C --> D["Display Everything"]
getUserId()
.then(id => fetchProfile(id))
.then(profile => loadPosts(profile.id))
.then(posts => displayPosts(posts))
.catch(err => console.log("Error:", err));
The Magic:
- Step 1: Get user ID
- Step 2: Use ID to fetch profile
- Step 3: Use profile to load posts
- Step 4: Display posts
If ANY step fails → the .catch() at the end catches it!
⚠️ Error Handling in Promises — Catching Problems
Errors in promises bubble up like a ball in water. They rise until something catches them!
Strategy 1: One Catch at the End
doStep1()
.then(r => doStep2(r))
.then(r => doStep3(r))
.catch(err => {
// Catches errors from ANY step!
console.log("Something broke:", err);
});
Strategy 2: Catch & Recover
fetchData()
.catch(err => {
console.log("Using backup data");
return backupData; // Recover!
})
.then(data => {
console.log("Got data:", data);
});
💡 Pro Tip: After .catch() returns a value, the chain continues normally!
🚀 Promise.all() — All Robots, GO!
Send multiple robots at once. Wait for ALL to return!
graph TD A["Promise.all"] --> B["Pizza Robot"] A --> C["Drink Robot"] A --> D["Dessert Robot"] B --> E["All Done!"] C --> E D --> E
Promise.all([
fetchPizza(),
fetchDrinks(),
fetchDessert()
])
.then(([pizza, drinks, dessert]) => {
console.log("Party ready!");
})
.catch(err => {
console.log("Someone failed:", err);
});
Key Rules:
- ✅ All succeed → you get ALL results in an array
- ❌ ONE fails → the whole thing fails immediately
- ⚡ Runs in parallel (fast!)
Use When: You need ALL things before continuing.
📊 Promise.allSettled() — Patient Results
Like .all(), but never fails. Waits for everyone and reports each result.
Promise.allSettled([
fetchPizza(), // Might succeed
fetchDrinks(), // Might fail
fetchDessert() // Might succeed
])
.then(results => {
results.forEach((r, i) => {
if (r.status === 'fulfilled') {
console.log(`#${i} worked:`, r.value);
} else {
console.log(`#${i} failed:`, r.reason);
}
});
});
Each Result Has:
status:'fulfilled'or'rejected'value: the result (if fulfilled)reason: the error (if rejected)
Use When: You want to know what happened to each promise, even if some fail.
🏎️ Promise.race() — First One Wins!
Multiple robots race. First one back wins—success OR failure!
Promise.race([
fetchFromServer1(), // Might be fast
fetchFromServer2(), // Might be slow
fetchFromServer3() // Might fail
])
.then(winner => {
console.log("First result:", winner);
})
.catch(err => {
console.log("First failure:", err);
});
Key Points:
- ⚡ Returns as soon as any promise settles
- Could be a success OR a failure
- Other promises keep running (but results ignored)
Use When: You just need the fastest response.
🏆 Promise.any() — First SUCCESS Wins!
Like .race(), but only cares about successes!
Promise.any([
fetchFromServer1(), // Might fail
fetchFromServer2(), // Might fail
fetchFromServer3() // Might succeed
])
.then(firstSuccess => {
console.log("Got one!", firstSuccess);
})
.catch(err => {
// Only runs if ALL fail
console.log("All failed:", err);
});
Comparison:
| Method | First to… |
|---|---|
.race() |
Settle (success OR fail) |
.any() |
Succeed only |
Use When: You have backup options and just need ONE to work.
🎯 Quick Summary
graph TD A["Promise Created"] --> B{Outcome?} B -->|Success| C[".then runs"] B -->|Failure| D[".catch runs"] C --> E[".finally runs"] D --> E
| Method | What It Does |
|---|---|
.then() |
Handle success |
.catch() |
Handle errors |
.finally() |
Run always |
| Chain | Connect steps |
Promise.all() |
Wait for ALL |
Promise.allSettled() |
Get ALL results |
Promise.race() |
First settles |
Promise.any() |
First succeeds |
💪 You’ve Got This!
Promises might seem tricky at first, but remember:
- They’re just robots on errands
.then()= when it works.catch()= when it doesn’t.finally()= always do this
You’re now ready to make your code handle the real world—where things don’t always work instantly, and that’s okay! 🚀
