Async & Promiseshard

Implement a minimal Promise class (then/catch)

Implement a simplified Promise class supporting asynchronous resolution, `then`, and `catch` chaining (educational subset of Promises/A+ behavior).

Asked at Apple, Meta, Google

#promises#internals#event loop

Answer

class MiniPromise {
  constructor(executor) {
    this.state = 'pending'
    this.value = undefined
    this.handlers = []

    const resolve = (value) => this._settle('fulfilled', value)
    const reject = (reason) => this._settle('rejected', reason)

    try {
      executor(resolve, reject)
    } catch (err) {
      reject(err)
    }
  }

  _settle(state, value) {
    if (this.state !== 'pending') return
    this.state = state
    this.value = value
    queueMicrotask(() => {
      this.handlers.forEach((h) => this._handle(h))
      this.handlers = []
    })
  }

  _handle(handler) {
    if (this.state === 'pending') {
      this.handlers.push(handler)
      return
    }

    const cb =
      this.state === 'fulfilled' ? handler.onFulfilled : handler.onRejected

    if (!cb) {
      ;(this.state === 'fulfilled' ? handler.resolve : handler.reject)(this.value)
      return
    }

    try {
      handler.resolve(cb(this.value))
    } catch (err) {
      handler.reject(err)
    }
  }

  then(onFulfilled, onRejected) {
    return new MiniPromise((resolve, reject) => {
      this._handle({ onFulfilled, onRejected, resolve, reject })
    })
  }

  catch(onRejected) {
    return this.then(undefined, onRejected)
  }
}

// Usage
new MiniPromise((resolve) => setTimeout(() => resolve(2), 10))
  .then((x) => x * 3)
  .then(console.log) // 6

Practise more Async & Promises questions →