In short
Data from an API never arrives instantly. A Promise is JavaScript's IOU: "I don't have the answer yet, but I'll tell you when I do, or tell you it failed."
An object representing the eventual result (or failure) of an asynchronous operation — the modern foundation for handling async code cleanly instead of nested callbacks. Promise composition makes asynchronous workflows easier to coordinate, including parallel operations, sequential dependencies, cancellation patterns, and error propagation.

Think of it like this
The token at the chaat stall
At a busy chaat stall you pay and get a token. The token isn't food, it's a promise of food. Either your number is called and you get pani puri (fulfilled), or they've run out (rejected). Meanwhile, you're free to chat with friends.
Watch it happen
Life of orderChaat(true)
orderChaat(true)
1/6Calling it creates a promise straight away. Its state is pending.
The big ideas
What you need to know
Three states
pending, then either fulfilled or rejected. Once settled, a promise never changes again.
.then, .catch, .finally
.then gets the value, .catch gets the error, .finally runs either way. Each returns a new promise, so you can chain.
Many at once
Promise.all waits for every promise and fails if any fails. Promise.allSettled waits for all and reports each result.
First one wins
Promise.race settles with whichever finishes first. Promise.any takes the first success.
See it in code
Walk through the code
1const orderChaat = (inStock) =>2 new Promise((resolve, reject) => {3 setTimeout(() => {4 if (inStock) resolve("Pani puri ready!");5 else reject(new Error("Sold out"));6 }, 1000);7 });8 9orderChaat(true)10 .then((food) => console.log(food)) // "Pani puri ready!" after 1s11 .catch((err) => console.log(err.message))12 .finally(() => console.log("Token closed"));1/4orderChaat returns a new Promise. resolve and reject are its two exits.
Try orderChaat(false). The .then is skipped, .catch logs "Sold out", and .finally still runs.
Save yourself the pain
Common mistakes
Oops
Forgetting return inside a .then, so the next .then gets undefined.
Do this instead
Return the value or promise you want passed along: .then((res) => res.json()).
Oops
Leaving out .catch.
Do this instead
An unhandled rejection shows up as a red error in the Console. Always end a chain with .catch.
Oops
Using Promise.all when some requests are allowed to fail.
Do this instead
Promise.all rejects on the first failure. Use Promise.allSettled to get every result, good or bad.
Your mission
Fake a slow API
Quick check
What's the order? console.log("1"); Promise.resolve().then(() => console.log("2")); console.log("3");
Go deeper
- 1Wrap a `setTimeout` in a Promise and consume it with `.then()`/`.catch()`. Validate your understanding by applying it in a small practical example.
- 2Practice `Promise.all()` to run multiple async operations in parallel. Test it with at least one normal case and one edge case so you can explain the behavior confidently.
- 3Learn the three states of a Promise: pending, fulfilled, rejected.
More topics at this stop
Stuck on this topic? Ask an Insider
Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.