Hey!
You've probably seen the word Promise in JavaScript and thought —
"What is this? Why does it exist? Why can't JavaScript just... do things normally?"
Fair question. Let's fix that today.
We're going to use a real online shopping flow to understand Promises — step by step, together.
And by the end, this code will make complete sense to you.
1. What Is a Promise? (Before We Touch the Code)
Imagine you order food online.
The app doesn't freeze while your food is being made. You go about your day. When it's ready — you get a notification.
That notification? That's a Promise resolving.
In JavaScript, a Promise is an object that says:
"I'll give you a result — but not right now. Give me some time. I'll get back to you."
A Promise has 3 possible states:
- Pending — still working, no result yet
- Resolved — finished successfully, here's your result
- Rejected — something went wrong, here's the error
Now let's see this in real code.
2. The Full Code — Look at It Once
function checkInternet() {
return new Promise((resolve, reject) => {
setTimeout(() => {
const online = true;
if (online) {
resolve("Internet connected ✅");
} else {
reject("No internet connection ❌");
}
}, 1000);
});
}
function loginUser() {
return new Promise((resolve) => {
setTimeout(() => {
resolve("User logged in ✅");
}, 1000);
});
}
function checkStock() {
return new Promise((resolve, reject) => {
setTimeout(() => {
const stockAvailable = true;
if (stockAvailable) {
resolve("Product in stock ✅");
} else {
reject("Product out of stock ❌");
}
}, 1500);
});
}
function processPayment() {
return new Promise((resolve, reject) => {
setTimeout(() => {
const paymentSuccess = true;
if (paymentSuccess) {
resolve("Payment successful ✅");
} else {
reject("Payment failed ❌");
}
}, 2000);
});
}
function placeOrder() {
return new Promise((resolve) => {
setTimeout(() => {
resolve("Order placed successfully ✅");
}, 1000);
});
}
function sendConfirmation() {
return new Promise((resolve) => {
setTimeout(() => {
resolve("Confirmation message sent ✅");
}, 1000);
});
}
checkInternet()
.then(result => {
console.log(result);
return loginUser();
})
.then(result => {
console.log(result);
return checkStock();
})
.then(result => {
console.log(result);
return processPayment();
})
.then(result => {
console.log(result);
return placeOrder(); })
.then(result => {
console.log(result);
return sendConfirmation();
})
.then(result => {
console.log(result);
console.log("Order completed successfully!");
})
.catch(error => {
console.log("❌ Error:", error);
});
Looks long, right?
Don't worry. We'll break it into small pieces. Each piece is actually very simple.
3. What's Actually Happening Here? — The Big Picture
This code simulates a complete online order flow.
Think of it like this — when you buy something online, the app runs these steps one after another:
Check Internet
↓
Login User
↓
Check Stock
↓
Process Payment
↓
Place Order
↓
Send Confirmation
↓
Done!
Each step waits for the previous one to finish before starting.
That's exactly what Promises and .then() do.
4. Let's Understand One Promise First
Let's take the simplest one — checkInternet.
function checkInternet() {
return new Promise((resolve, reject) => {
setTimeout(() => {
const online = true;
if (online) {
resolve("Internet connected ✅");
} else {
reject("No internet connection ❌");
}
}, 1000);
});
}
Let's read this line by line 👇
return new Promise((resolve, reject) => {
→ We're creating a new Promise. It takes two things — resolve and reject. These are functions JavaScript gives us.
setTimeout(() => { ... }, 1000)
→ Wait 1 second before doing anything. This simulates real network delay.
const online = true
→ This is our fake condition. In a real app, this would check your actual internet.
if (online) { resolve("Internet connected ✅") }
→ If internet is available — call resolve. Promise is successful. ✅
else { reject("No internet connection ❌") }
→ If no internet — call reject. Promise failed. ❌
That's it. That's one complete Promise.
*5. Quick Question for You *
Look at loginUser:
function loginUser() {
return new Promise((resolve) => {
setTimeout(() => {
resolve("User logged in ✅");
}, 1000);
});
}
Did you notice something different from checkInternet?
Take a second. Look carefully.
...
It only has resolve — no reject.
Why? Because in this code, login always succeeds. There's no failure case written for it. So we only need resolve.
Simple — but important to notice. 👀
6. Now Let's Talk About resolve and reject
These two are the heart of every Promise.
resolve → "Everything went well. Here's the result. Move to the next step."
reject → "Something went wrong. Stop here. Jump to .catch()."
Here's a clear picture of which functions can fail and which always succeed:
| Function | Can Fail? | Why |
|---|---|---|
checkInternet() |
✅ Yes | Internet might be off |
loginUser() |
❌ No | Always resolves |
checkStock() |
✅ Yes | Item might be out of stock |
processPayment() |
✅ Yes | Payment might fail |
placeOrder() |
❌ No | Always resolves |
sendConfirmation() |
❌ No | Always resolves |
Functions that can fail have both resolve and reject.
Functions that always succeed only have resolve.
7. What Does .then() Actually Do?
Now the fun part. Look at how we run all 6 steps:
checkInternet()
.then(result => {
console.log(result);
return loginUser();
})
.then(result => {
console.log(result);
return checkStock();
})
.then(result => {
console.log(result);
return processPayment();
})
...
Let's understand .then() clearly.
.then() runs only when the previous Promise resolves successfully.
It receives the resolved value as result — and you can use it however you want.
Then — you return the next Promise inside it. That's what creates the chain.
Think of it like a relay race :
Runner 1 finishes → passes the baton → Runner 2 starts → passes the baton → Runner 3 starts...
Each .then() is one runner. Each return is passing the baton.
8. Step-by-Step Output — Let's Walk Through It Together
Here's what happens when you run this code:
Waits 1 second...
Internet connected ✅
Waits 1 more second...
User logged in ✅
Waits 1.5 seconds...
Product in stock ✅
Waits 2 seconds...
Payment successful ✅
Waits 1 second...
Order placed successfully ✅
Waits 1 second...
Confirmation message sent ✅
Order completed successfully!
Each step runs one at a time, in order. The next step never starts before the previous one finishes.
That's the power of Promise chaining.
9. What About .catch()? — The Safety Net
.catch(error => {
console.log("❌ Error:", error);
});
This is your safety net.
If any Promise in the entire chain calls reject — the whole chain stops and jumps straight to .catch().
Let's say you change this in checkStock:
const stockAvailable = false; // changed to false
The output would be:
Internet connected ✅
User logged in ✅
❌ Error: Product out of stock ❌
Everything after checkStock — payment, order, confirmation — none of it runs.
One failure. Whole chain stops. .catch() handles it.
Clean. Safe. Controlled.
*10. Small Challenge for You *
Before you move on — try this mentally.
What happens if you change this line in processPayment:
const paymentSuccess = false; //
What will the output be?
Think about it.
...
Answer:
Internet connected ✅
User logged in ✅
Product in stock ✅
❌ Error: Payment failed ❌
The chain ran fine until payment failed. Then .catch() caught it. Order never placed. Confirmation never sent.
Makes sense, right? That's exactly how real apps work.
Quick Summary — 5 Things to Remember
A Promise = a future result — it's either going to succeed (
resolve) or fail (reject). Not both.resolve= success — moves to the next.then()in the chain.reject= failure — skips everything and jumps straight to.catch()..then()chains steps — each step waits for the previous one to finish before starting..catch()is your safety net — one place to handle any error from anywhere in the chain.
Promises feel confusing at first because they're about time — things happening later, not immediately.
But once you see it as a relay race — one step finishing and passing to the next — it starts to click.
Try running this code yourself. Change true to false in different places and watch what happens. That hands-on experiment will teach you more than any explanation.
Got a question? Drop it in the comments. No question is too basic — ask away.
Thanks for reading! Keep building, one Promise at a time.
Top comments (0)