Interview answer drill

Use this JavaScript interview question to rehearse a quick answer, common mistake, follow-up, and production pitfall.

Promise - Fundamental UnderstandingFrontend interview answer

HighIntermediateJavascript
Interview focus

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
Practice more JavaScript interview questions
Interview quick answer

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.

Full interview answer

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.

These four rules explain most Promise behavior.
JAVASCRIPT
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)

JAVASCRIPT
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.

JAVASCRIPT
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.

Promise chain behavior is deterministic, not magic.

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 you return or throw.

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 catch blocks that hide the original failure path.

Still so complicated?

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.

Summary
  • Executor is synchronous; handlers are microtasks.
  • Promise settles once.
  • Each chain step returns a new Promise.
  • finally() is cleanup, not a value-transform shortcut.
Similar questions
Guides
Preparing for interviews?

Use this as one explanation rep, then continue with the JavaScript interview questions cluster or a guided prep path.