Not returning inside then chains
If a then callback starts async work but does not return the Promise, the outer chain continues early and loses proper sequencing.
Fix: Always return the next value or Promise from then callbacks.
Loading...
See how JavaScript Promises work with an interactive visualization. Step through pending, fulfilled, and rejected states, promise chaining, microtask scheduling, and async/await flow.
Loading visualization...
Promises represent the eventual result of asynchronous work, enabling deterministic chaining, centralized error handling, and readable async flows with async and await.
A Promise has three states: pending, fulfilled, and rejected. Once settled, its state and value are immutable.
Handlers registered with then, catch, and finally do not run immediately. They are queued as microtasks and executed after the current call stack clears.
Promises allow composition of async operations so data flow and failure paths are explicit instead of deeply nested callbacks.
Interview framing: define Promises in one sentence, then explain one concrete runtime behavior and one common pitfall with a short code example.
If a then callback starts async work but does not return the Promise, the outer chain continues early and loses proper sequencing.
Fix: Always return the next value or Promise from then callbacks.
Combining then chains and async/await carelessly can create unhandled rejections or swallowed errors.
Fix: Use one style consistently per flow and ensure errors are handled with catch or try/catch.
Manual wrapping adds complexity and increases risk of never resolving or rejecting correctly.
Fix: Prefer direct chaining and Promise utilities like Promise.all, allSettled, and race.
Common interview prompts with concise model answers.
Promise handlers are microtasks, and the event loop drains microtasks before moving to the next macrotask queue item like setTimeout.
Promise.resolve()
.then(() => "A")
.then((value) => console.log(value))
.catch((error) => console.error(error));Yes. Thrown errors in then callbacks reject the next Promise in the chain, and catch can handle that rejection.
Promise.all fails fast on the first rejection, while Promise.allSettled waits for all Promises and returns each outcome.
No. async/await is syntax built on top of Promises; underlying scheduling and resolution behavior still follows Promise rules.
Continue with these concepts to strengthen your mental model.
const promise = new Promise((resolve, reject) => { console.log("executor"); resolve("done");}); promise.then((val) => { console.log(val);}); console.log("after");empty
empty
No output yet.