Creating a promise
Producer side.
new Promise((resolve, reject) => { ... })— constructor takes an executor function.- Executor runs synchronously — immediately when the promise is created.
- Call
resolve(value)on success,reject(error)on failure — state changes from pending. - Return the promise to the consumer, otherwise they can’t attach handlers.
Chaining rules
Data flows via return.
- Each
.then()returns a NEW promise → keep chaining top-to-bottom. - Whatever you return becomes the next .then’s input. Forget to return → next .then gets
undefined. - Return a value → next .then gets the value. Return a promise → chain waits for it.
resolve()does NOT stop the executor — alwaysreturnafter reject to prevent fallthrough.
Error handling patterns
.catch placement matters.
- A
.catch()catches errors from all steps above it — not below. .thenAFTER.catchstill runs — catch returns a resolved promise withundefined.- Multiple
.catchblocks = selective error handling at different chain levels. - Always add at least one
.catch— unhandled rejections can crash Node or warn in browsers.
async function
Always returns a promise.
- Plain return value → auto-wrapped in
Promise.resolve(value). - Already a promise → returned as-is (no double-wrapping).
- Enables
awaitinside the function body — normal functions cannot useawait. - Since async functions return promises, you can
.then()or.catch()their result.
await — what actually happens
Suspends the function, not the engine.
awaitpauses the async function and pops it off the call stack — stack is NEVER blocked.- Other code, event handlers, and UI continue running freely while the function is suspended.
- When the awaited promise settles, the event loop pushes the function back; it resumes exactly where it left off.
await "value"(non-promise) still creates a microtask pause — the line after await runs as a microtask.
The timing trap
Promises start at creation, not await.
const p1 = new Promise(...)starts the timer/work immediately — even before any await.- Two promises created upfront with different delays both tick in parallel.
- To get truly sequential execution, create promises inside the async function via factory calls.
fetch()needs two awaits — one for the Response headers, one for.json()body parsing.
Comments
Comments are disabled in this environment. Set
PUBLIC_GISCUS_REPO,PUBLIC_GISCUS_REPO_ID, andPUBLIC_GISCUS_CATEGORY_IDto enable.