JavaScript — Promises
A promise = a receipt for a future value
Fetching data takes time. Instead of blocking, you get a promise — an IOU:
pending → fulfilled (value) ✓
→ rejected (error) ✗
Creating & consuming
function wait(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
wait(1000).then(() => console.log("one second later"));
The executor runs immediately; resolve(value) fulfills, reject(error) fails:
const coinFlip = new Promise((resolve, reject) => {
Math.random() < 0.5 ? resolve("heads") : reject(new Error("tails!"));
});
coinFlip
.then(result => console.log("got:", result))
.catch(err => console.error("failed:", err.message))
.finally(() => console.log("flip complete"));
| Handler | Runs when |
|---|---|
.then(v) | fulfilled |
.catch(e) | rejected |
.finally() | either way |
Chaining — the flat pyramid cure
.then returns a NEW promise, enabling sequences instead of nesting:
getUser(7)
.then(user => getPosts(user.id)) // return promise → waits
.then(posts => posts[0])
.then(post => post.title)
.then(console.log)
.catch(handleAnyFailure); // ONE catch guards the chain
Values flow through: whatever a .then returns becomes the next input.
async/await — promises with better clothes
async function loadTitle() {
try {
const user = await getUser(7); // pause HERE until settled
const posts = await getPosts(user.id);
return posts[0].title;
} catch (e) {
return "unavailable";
}
}
loadTitle().then(console.log);
await works only inside async functions; it unwraps promises while keeping try/catch ergonomics. Under the hood it's still promises — same machinery, friendlier syntax. Modern default style.
Parallel vs sequential
// sequential: ~2s total (each waits for the last)
const a = await fetchA();
const b = await fetchB();
// parallel: ~1s total (both in flight together)
const [ra, rb] = await Promise.all([fetchA(), fetchB()]);
| Helper | Behavior |
|---|---|
Promise.all | wait all; rejects fast on ANY failure |
Promise.allSettled | wait all; never rejects; inspect each outcome |
Promise.race | first to settle wins |
Promise.any | first success |
const results = await Promise.allSettled([p1, p2]);
results.filter(r => r.status === "fulfilled").map(r => r.value);
Converting callback APIs
Wrap old-style functions once:
const delay = ms => new Promise(res => setTimeout(res, ms));
await delay(500);
Common mistakes: forgetting
await(you hold a promise object, not data); mixingreturn awaitconfusion in try/catch; creating executor promises when a plain value would do (Promise.resolve(x)).
Mini Practice
- Build retryable(delay, fn) that re-runs on rejection up to 3 times
- Fetch two URLs in parallel via Promise.all; time both strategies
- Convert one .then chain into async/await + try/catch
- Use race() for a timeout wrapper around a slow task
- allSettled three flaky promises; print per-item outcomes
Next: fetch →
Related Topics
Frequently Asked Questions about Promises
What is Promises in JavaScript?
Promises is a fundamental concept in JavaScript. This lesson explains it step by step with clear examples, making it easy for beginners to understand.
How do I learn Promises?
Start by reading the explanation above, then try the code examples. Practice by modifying the examples and experimenting with different values. Hands-on practice is the best way to learn Promises.
Why is Promises important in JavaScript?
Promises is essential for JavaScript development. Understanding this concept will help you write better code and solve real-world problems more effectively.