Promises & Promise Combinators
Promise হলো state machine — pending, fulfilled, rejected
1. The Three States
2. Creating a Promise
const p = new Promise((resolve, reject) => {
setTimeout(() => {
if (Math.random() < 0.5) resolve("ok!");
else reject(new Error("failed"));
}, 100);
});
p.then(v => console.log("value:", v))
.catch(e => console.log("error:", e.message))
.finally(() => console.log("done"));
new Promise((resolve, reject) => {...})। ফলাফল pending থেকে fulfilled (resolve) বা rejected (reject) হয় — শুধু একবার।3. Chaining
Each .then returns a new Promise. Whatever you return from a handler becomes the next Promise's value. Throw inside any handler and the chain skips to .catch.
Promise.resolve(2)
.then(n => n + 1)
.then(n => n * 10)
.then(n => { if (n > 20) throw new Error("too big"); return n; })
.then(console.log)
.catch(e => console.log("caught:", e.message));
.then
If you forget return, the next .then sees undefined and fires immediately — async results vanish. Use async/await next module to make this impossible.
4. The Four Combinators
| Method | Resolves with | Rejects when |
|---|---|---|
Promise.all | Array of all values | Any one rejects (fail-fast) |
Promise.allSettled | Array of {status, value/reason} | Never |
Promise.race | First to settle (resolve or reject) | If first to settle rejects |
Promise.any | First to fulfill | All reject (AggregateError) |
const ok = (v, ms = 10) => new Promise(r => setTimeout(() => r(v), ms));
const fail = (e, ms = 10) => new Promise((_, j) => setTimeout(() => j(e), ms));
(async () => {
console.log("all:",
await Promise.all([ok(1), ok(2), ok(3)]));
console.log("allSettled:",
await Promise.allSettled([ok(1), fail("x"), ok(3)]));
console.log("race:",
await Promise.race([ok("slow", 100), ok("fast", 10)]));
console.log("any:",
await Promise.any([fail("x"), ok("y")]));
})();
5. Promisify a Callback API
const promisify = fn => (...args) =>
new Promise((res, rej) =>
fn(...args, (err, data) => err ? rej(err) : res(data)));
const readDelay = (key, cb) => setTimeout(() => cb(null, `value of ${key}`), 10);
const readP = promisify(readDelay);
readP("foo").then(console.log);
6. Common Bugs
- Forgetting
returninside a.then— the chain races ahead - Swallowing errors by missing the final
.catch - Mixing then/catch with the wrong order —
.then(handle).catch(...)only catches errors fromhandletoo, but not from inside.then(success, fail)form - Wrapping a promise in
new Promise— that's the "Promise constructor anti-pattern" - Resolving with a Promise — that's fine; it gets unwrapped automatically
7. Glossary (শব্দকোষ)
| Term | Meaning | বাংলায় |
|---|---|---|
| Promise | State machine: pending → fulfilled (value) or rejected (reason). | State machine: pending → fulfilled / rejected। |
resolve / reject | Functions that move a Promise from pending into a settled state. | Promise-কে settle করার দুটি function। |
| Settled | Either fulfilled or rejected — no longer pending. | Pending নয় — fulfilled বা rejected অবস্থা। |
.then | Adds a callback for fulfillment; returns a new Promise. | Fulfillment-এ callback; নতুন Promise ফেরত দেয়। |
.catch | Shorthand for .then(undefined, onReject). | .then(undefined, onReject)-এর সংক্ষেপ। |
.finally | Always runs once the chain settles. | Chain settle হলেই চলে — cleanup-এ ব্যবহৃত। |
Promise.all | Resolves with all values; fails fast on any rejection. | সব value-র array; যেকোনো rejection-এ fail। |
Promise.allSettled | Always resolves with status objects. | সব result সংগ্রহ — কখনো reject হয় না। |
Promise.race | Settles with the first promise to settle. | প্রথম settle-হওয়া Promise-এর সাথে settle। |
Promise.any | Resolves with the first fulfilled; rejects only if all reject. | প্রথম fulfilled; সব fail হলে AggregateError। |
.then নতুন Promise দেয়; ভেতরে throw করলে chain skip করে .catch-এ চলে যায়। চারটি combinator (all/allSettled/race/any) মুখস্থ থাকলে যেকোনো async pattern সাজানো যায়।
8. Practice Problems
- Create a Promise that resolves to "hi" after 50 ms.
✨ Show Answer
a1.jsnew Promise(r => setTimeout(() => r("hi"), 50)).then(console.log); - Chain three increments using
.then.✨ Show Answer
a2.jsPromise.resolve(0) .then(n => n + 1) .then(n => n + 1) .then(n => n + 1) .then(console.log); - Catch a rejected Promise and print its message.
✨ Show Answer
a3.jsPromise.reject(new Error("oops")) .catch(e => console.log("caught:", e.message)); - Use
Promise.allto await three timers.✨ Show Answer
a4.jsconst wait = ms => new Promise(r => setTimeout(() => r(ms), ms)); Promise.all([wait(10), wait(20), wait(30)]).then(console.log); - Use
Promise.allSettledwith one rejected Promise.✨ Show Answer
a5.jsPromise.allSettled([ Promise.resolve(1), Promise.reject("x"), Promise.resolve(3) ]).then(console.log); - Race two timers and print the faster.
✨ Show Answer
a6.jsconst wait = (v, ms) => new Promise(r => setTimeout(() => r(v), ms)); Promise.race([wait("slow", 200), wait("fast", 20)]).then(console.log); - Use
Promise.anywith one fail and one success.✨ Show Answer
a7.jsPromise.any([ Promise.reject("x"), Promise.resolve("ok") ]).then(console.log); - Build a
delay(ms)Promise utility.✨ Show Answer
a8.jsconst delay = ms => new Promise(r => setTimeout(r, ms)); delay(30).then(() => console.log("after 30ms")); - Implement
timeout(promise, ms)that rejects if the inner promise is too slow.✨ Show Answer
a9.jsconst timeout = (p, ms) => Promise.race([ p, new Promise((_, rej) => setTimeout(() => rej(new Error("timeout")), ms)) ]); const slow = new Promise(r => setTimeout(() => r("done"), 200)); timeout(slow, 50).catch(e => console.log(e.message)); - Show that throwing inside a
.thenjumps to.catch.✨ Show Answer
a10.jsPromise.resolve(1) .then(() => { throw new Error("boom"); }) .then(() => console.log("skipped")) .catch(e => console.log("caught:", e.message)); - Promisify
setTimeoutassleep(ms)usingnew Promise.✨ Show Answer
a11.jsconst sleep = ms => new Promise(r => setTimeout(r, ms)); (async () => { await sleep(20); console.log("slept"); })(); - Run two promises in parallel and sum results.
✨ Show Answer
a12.jsconst ok = (v, ms) => new Promise(r => setTimeout(() => r(v), ms)); Promise.all([ok(10, 20), ok(15, 10)]) .then(([a, b]) => console.log(a + b)); - Why does
Promise.allfail-fast?✨ Show Answer
Answer: By design — once any input rejects, the aggregate has nothing useful to deliver, so it rejects immediately and lets you handle the failure. If you want to wait for every result and inspect successes and failures separately, use
Promise.allSettled. - Demonstrate that resolving with a Promise unwraps it automatically.
✨ Show Answer
a14.jsconst nested = Promise.resolve(Promise.resolve(42)); nested.then(console.log); // 42, not a Promise - Use
.finallyto run cleanup whether the chain succeeds or fails.✨ Show Answer
a15.jsPromise.resolve(1) .then(console.log) .finally(() => console.log("cleanup ok")); Promise.reject("x") .catch(e => console.log("err:", e)) .finally(() => console.log("cleanup err")); - Build a retry helper:
retry(fn, n).✨ Show Answer
a16.jsasync function retry(fn, n) { let last; for (let i = 0; i < n; i++) { try { return await fn(); } catch (e) { last = e; } } throw last; } let i = 0; retry(() => ++i < 3 ? Promise.reject("nope") : Promise.resolve("ok"), 5) .then(console.log); - Show the "forgot to return inside .then" bug.
✨ Show Answer
a17.jsconst wait = ms => new Promise(r => setTimeout(() => r(ms), ms)); // BUG — forgot return Promise.resolve().then(() => { wait(50); }) .then(v => console.log("bug got:", v)); // undefined! // FIX — return the promise Promise.resolve().then(() => wait(50)) .then(v => console.log("fix got:", v)); - Why is mixing
then(success, fail)with.catchconfusing? In one paragraph.✨ Show Answer
Answer: The two-arg form
.then(success, fail)only catches rejections from the upstream Promise — it cannot catch errors thrown inside its ownsuccesshandler. A trailing.catchcan. Mixing both makes it ambiguous which errors land where; prefer.then(success).catch(...)orasync/await + try/catch.
Summary — Module 22
A Promise is a state machine — pending until it settles, then permanently fulfilled or rejected. Chain with .then/.catch/.finally. Combine with all, allSettled, race, any. Always return inside .then; always end the chain with .catch.
.then chain এবং চারটি combinator মনে রাখুন। return ভুলবেন না।