Skip to the solution
MediumDSA6 min read

What are Promises in Node.js and how do they improve async code?

957 views

The problem

Question presented to candidate: "Explain what a Promise actually is β€” not just how to use .then() β€” and why it was worth adding to the language on top of plain callbacks."

What a strong answer should cover:

  • A Promise is an object representing the eventual result of an async operation β€” it exists in one of exactly three states: pending, fulfilled (with a value), or rejected (with a reason), and once fulfilled or rejected, it is permanently settled β€” it can never change state again.
  • .then(onFulfilled, onRejected) registers callbacks for the eventual outcome and itself returns a new Promise, which is what makes chaining (.then().then()) possible β€” each .then() can return a value, or another Promise, and the chain waits for it.
  • .catch(fn) is exactly .then(undefined, fn) β€” syntactic sugar for handling a rejection, and critically, it catches a rejection from any earlier step in the chain, not just the immediately preceding one, which is the main ergonomic win over per-step callback error handling.
  • Promise.all([...]) runs multiple Promises concurrently and resolves when all succeed (or rejects as soon as any one does); Promise.allSettled([...]) waits for all of them regardless of individual success/failure and reports each outcome β€” a distinct, commonly-confused-with-all tool.
  • Promise .then/.catch callbacks are scheduled as microtasks β€” they always run after the current synchronous code finishes and after process.nextTick's queue, but before the next macrotask (a setTimeout, an I/O callback) β€” this timing guarantee is itself a real, testable claim, not just a style preference.
  • async/await is not a different mechanism β€” an async function always returns a Promise, and await is syntax for consuming one; understanding Promises underneath is what makes async/await's behavior (including error propagation) predictable rather than magic.

Clarifying questions expected:

  • "Does the interviewer want the mechanics (states, microtask timing) or just usage patterns?" β€” these are different depths of the same topic.
  • "Is error handling for one step or the whole chain the actual concern here?" β€” decides whether to reach for a single trailing .catch or a .then(ok, err) pair at one step.

Code / implementation expected: Yes β€” a chain with a deliberate mid-chain rejection actually caught by a single trailing .catch, plus a real timing check proving the microtask-before-macrotask ordering, is the concrete deliverable.

  • promises
  • asynchronous
  • error handling
  • es6

Try it yourself

Sketch your approach before you read the solution. That is what the interview tests.

Stuck? Get a hint.

A short nudge toward the approach. It will not give the answer away.

Solution

The solution is hidden so you can try first

6 min read Β· 9 sections

Read the code

JavaScriptA single try/catch catching a mid-chain rejection, plus the measured sequential-vs-Promise.all timing difference
function wait(ms, label) { return new Promise((r) => setTimeout(() => r(label), ms)); }

async function mayReject(shouldFail) {
  if (shouldFail) throw new Error("boom");
  return "ok";
}
try {
  await mayReject(true);
} catch (e) {
  console.log("caught rejected await:", e.message); // caught rejected await: boom
}

const t0 = Date.now();
await wait(100); await wait(100); await wait(100);
console.log("sequential:", Date.now() - t0, "ms"); // sequential: 315 ms

const t1 = Date.now();
await Promise.all([wait(100), wait(100), wait(100)]);
console.log("Promise.all:", Date.now() - t1, "ms"); // Promise.all: 108 ms

Discussion

Other approaches, follow-ups and how it went in real interviews.

Sign in to join the discussion.

No comments yet. Share how you would answer it.

Question 56 of 152 in Node.js

Keep your momentum going.

Mark this question solved to track your progress, then take the next one while it is fresh.

All Node.js questions
Up nextMedium

What is Helmet and which HTTP security headers should a Node.js API set?

Continue