Docs

JS Machine Coding Questions — Implementations You Must Know

Promise — Build from Scratch


  • Implement a MyPromise class with resolve, reject, .then, and .catch.
  • Key insight: Store state (pending/fulfilled/rejected) and value. Queue .then callbacks — run them when the promise settles. Chaining works by returning a new MyPromise from each .then.
  • Gotcha: A promise can only transition once — guard with if (state !== 'pending') return.
  • Gotcha: If .then callback itself throws, the returned promise must reject.
  • Gotcha: Real Promises run callbacks asynchronously (microtask queue) — simplified version runs them synchronously.
1class MyPromise { 2 constructor(executor) { 3 this.state = "pending"; 4 this.value = undefined; 5 this.onFulfilledCbs = []; 6 this.onRejectedCbs = []; 7 8 const resolve = (value) => { 9 if (this.state !== "pending") return; 10 this.state = "fulfilled"; 11 this.value = value; 12 this.onFulfilledCbs.forEach(cb => cb(value)); 13 }; 14 const reject = (reason) => { 15 if (this.state !== "pending") return; 16 this.state = "rejected"; 17 this.value = reason; 18 this.onRejectedCbs.forEach(cb => cb(reason)); 19 }; 20 try { executor(resolve, reject); } 21 catch (e) { reject(e); } 22 } 23 24 then(onFulfilled, onRejected) { 25 return new MyPromise((resolve, reject) => { 26 const handleFulfill = (value) => { 27 try { resolve(onFulfilled ? onFulfilled(value) : value); } 28 catch (e) { reject(e); } 29 }; 30 const handleReject = (reason) => { 31 try { resolve(onRejected ? onRejected(reason) : (() => { throw reason; })()); } 32 catch (e) { reject(e); } 33 }; 34 if (this.state === "fulfilled") handleFulfill(this.value); 35 else if (this.state === "rejected") handleReject(this.value); 36 else { 37 this.onFulfilledCbs.push(handleFulfill); 38 this.onRejectedCbs.push(handleReject); 39 } 40 }); 41 } 42 43 catch(onRejected) { return this.then(null, onRejected); } 44 static resolve(value) { return new MyPromise(res => res(value)); } 45 static reject(reason) { return new MyPromise((_, rej) => rej(reason)); } 46}