What are Promises in JavaScript
Objects representing the eventual outcome of an async operation. Three states: pending → fulfilled or rejected, settled once and then immutable. Read via `.then` / `.catch` / `.finally` or await. Static aggregators: `Promise.all`, `allSettled`, `race`, `any`. Replaced callbacks with composable async.
Cross-link to [[what-is-a-promise-in-javascript-how-do-you-resolve-a-promise-and-what-are-its-us]] which goes deeper. Short version.
States
pending → fulfilled (with value)
→ rejected (with reason)Settles once. Immutable after.
Creating
const p = new Promise((resolve, reject) => {
setTimeout(() => resolve("done"), 100);
});
p.then((v) => console.log(v));Or:
Promise.resolve("immediate");
Promise.reject(new Error("bad"));Consuming
p
.then((v) => transform(v))
.catch((e) => handle(e))
.finally(() => cleanup());Or with await:
try {
const v = await p;
} catch (e) {
handle(e);
} finally {
cleanup();
}Aggregators
| Resolves | Rejects | |
|---|---|---|
Promise.all | All fulfill | First rejection |
Promise.allSettled | All settle | Never |
Promise.race | First settles | First settles with rejection |
Promise.any | First fulfills | All rejected → AggregateError |
Why they exist
Before promises:
getUser(id, (err, u) => {
if (err) return cb(err);
getPosts(u.id, (err, p) => { if (err) return cb(err); render(p); });
});With:
const u = await getUser(id);
const p = await getPosts(u.id);
render(p);Microtasks
.then callbacks run on the microtask queue — before the next macrotask:
setTimeout(() => console.log("A"), 0);
Promise.resolve().then(() => console.log("B"));
// B, then AAnti-patterns
- Promise constructor anti-pattern — wrapping an existing Promise. Just return it.
- Forgetting return inside .then — breaks the chain.
- Unhandled rejections — eventually crash Node.
Interview framing
"A Promise represents an async operation's eventual outcome — pending → fulfilled or rejected, settled once. Create with new Promise((res, rej) => ...) or Promise.resolve / reject. Consume with .then / .catch / .finally or await. Aggregators (Promise.all / allSettled / race / any) let you compose multiple promises. They replaced callback hell with flat, composable async — same single error path via .catch or try/catch. .then callbacks run on the microtask queue, which is why a chained .then always runs before the next setTimeout."
Follow-up questions
- •Show me an example of composing multiple promises.
- •What's the microtask queue?
- •How does async/await relate?
Common mistakes
- •Constructor anti-pattern.
- •No .catch / try/catch.
- •Missing return inside .then.
Performance considerations
- •Microtask floods can starve I/O. Promises themselves are cheap.
Edge cases
- •Resolving with another Promise — chains.
- •Multiple resolve calls — first wins.
- •Synchronous throw in executor → rejection.
Real-world examples
- •fetch, fs.promises, db.query, browser async APIs.