Promise fundamentals are under-the-hood mechanics: executor timing, single settlement, chain propagation, and microtask ordering. Strong answers also explain UI-order debugging, missing-return bugs, and why settlement is not the same as a callback already running.
Use this JavaScript interview question to rehearse a quick answer, common mistake, follow-up, and production pitfall.
Promise - Fundamental UnderstandingFrontend interview answer
This JavaScript interview question tests whether you can explain JavaScript Promises under the hood: timing, missing returns, and finally, connect it to production trade-offs, and handle common follow-up questions.
- JavaScript Promises under the hood: timing, missing returns, and finally explanation without falling back to memorized docs wording
- Promise and Asynchronous Javascript reasoning, edge cases, and production failure modes
- How you would answer the most likely JavaScript interview follow-up
Core mental model
A Promise is a one-way state machine: pending -> fulfilled or pending -> rejected. The useful part is understanding it under the hood: the executor runs immediately, callbacks wait as microtasks, and tiny mistakes like a missing return can change what the UI renders later.
Mechanic | Reality |
|---|---|
Executor timing | Runs immediately when Promise is created. |
then/catch timing | Callbacks run later as microtasks. |
Settlement | First resolve/reject wins; later calls ignored. |
Chaining | Each then returns a fresh Promise. |
console.log('A');
const p = new Promise((resolve) => {
console.log('B executor');
resolve(1);
resolve(2); // ignored
});
p.then(v => console.log('C then:', v));
console.log('D');
// Output: A, B executor, D, C then: 1
Chain propagation rules (must know)
Promise.resolve(10)
.then(v => v + 1) // next gets 11
.then(v => Promise.resolve(v * 2)) // waits, next gets 22
.then(() => { throw new Error('boom'); })
.catch(err => {
console.log(err.message); // boom
return 7; // recovery value
})
.then(v => console.log(v)); // 7
Worked debug example
This is the kind of production bug interviewers care about: the Promise is already settled, but the render callback still waits in the microtask queue, and one missing return silently turns the next value into undefined.
console.log('sync start');
Promise.resolve('u42')
.then((id) => {
console.log('then 1', id);
return { id, name: 'Ada' };
})
.then((user) => {
console.log('then 2', user.name);
return user.name; // remove this return and the next handler gets undefined
})
.finally(() => {
console.log('finally cleanup');
})
.then((name) => {
console.log('render', name);
});
console.log('sync end');
// Output:
// sync start
// sync end
// then 1 u42
// then 2 Ada
// finally cleanup
// render Ada
If handler returns... | Next link receives... |
|---|---|
Plain value | Fulfilled Promise with that value. |
Promise/thenable | Resolved/rejected result of that Promise. |
Thrown error | Rejected Promise with that error. |
Likely follow-up confusion
- Promise state and callback scheduling are not the same thing: a Promise can already be fulfilled while your
.then()callback is still waiting as a microtask. finally()runs after settlement, but it does not replace the chain value unless it throws or returns a rejecting Promise.- Each
.then()creates a fresh Promise, so value flow depends on what youreturnorthrow.
Practical scenario
A checkout screen shows a spinner, then loads profile -> shipping -> payment intent. If one .then() forgets to return parsed data, the next render step gets undefined even though the Promise already settled correctly.
Common pitfalls
- Missing return in
.then()handlers. - Assuming a fulfilled Promise means the UI callback already ran.
- Using broad
catchblocks that hide the original failure path.
A Promise chain is like a relay race: each runner must pass the baton (return). If one runner drops it, the next runner gets nothing.
- Executor is synchronous; handlers are microtasks.
- Promise settles once.
- Each chain step returns a new Promise.
finally()is cleanup, not a value-transform shortcut.
Use this as one explanation rep, then continue with the JavaScript interview questions cluster or a guided prep path.