Skip to solution
hardDSA

How do you implement a simple Promise library from scratch?

179 views
01

Understand the problem

Question presented to candidate: "Implement a simplified version of the Promise class from scratch — the constructor, then, catch, and finally. It needs to correctly handle chaining, a handler that throws, a handler that returns another promise or thenable, and calling resolve more than once. How do you make sure then callbacks run asynchronously, the way real Promise callbacks do, instead of synchronously?"

What a strong answer should cover:

  • A Promise has exactly three states — pending, fulfilled, rejected — and once it leaves pending it can never change state again; calling resolve or reject a second time is a genuine no-op.
  • .then() must return a NEW promise, not the same one, which is what makes chaining (.then().then().then()) work at all — each .then() call's return value becomes the next link's input.
  • If a .then() handler throws, the returned promise must reject with that thrown value, and that rejection should propagate to the next .catch(), skipping over any .then() calls without a rejection handler in between.
  • If resolve is called with a thenable (any object with a callable .then, not just another instance of this exact class), the outer promise must wait for and adopt that thenable's eventual state, recursively, not just fulfill immediately with the thenable object itself.
  • Callbacks registered with .then() must run asynchronously even if the promise is already settled by the time .then() is called — real Promises always defer to a microtask, never call a handler synchronously inline.
  • .finally() runs its callback on both success and failure, and does not change the eventual value or error — it passes both straight through.

Clarifying questions expected:

  • "Should pending callbacks be stored per-promise and flushed once it settles, or is there a simpler model you would prefer to reach for first?" — tests whether the candidate understands why a callback queue is structurally necessary.
  • "Is queueMicrotask available in this environment, or should I simulate microtask timing with something like Promise.resolve().then() or setTimeout as a fallback?" — a real, practical environment question, since queueMicrotask itself is a relatively recent global.

Code / implementation expected: Yes — a full, runnable implementation plus a real test suite proving chaining, error propagation, thenable adoption, and — critically — that its actual microtask ordering matches native Promise exactly.

promisespolyfillasync
02

Attempt it yourself

Sketch your approach before reading the solution — that's what interviews test.

Nudge consolestandby

Stuck? Beam a request up — the console returns a conceptual nudge that guides your logic without spoiling the implementation.

03

Study the solution

Target Audience: Engineers preparing for JavaScript async/Promise interview questions. Difficulty: Hard

How to read this doc: Concepts are explained in plain language first, then tagged with 📌 Interview term:. Every test result shown below is real, captured output from actually running

Solution ready — 2 min read

Classified // press E to declassify

04

Run the code

JSMyPromise, a from-scratch Promise implementation, plus its real 10-group test suite (run directly)
05

Join the discussion

Discussion (0)

Sign in to join the discussion.

No responses yet. Be the first to share what you think.

Transmission complete // awaiting log

KEEP THE
STREAK ALIVE.

Dossier 161 of 165 decoded in the JavaScript track. One more won't hurt.

Back to track