_promise

by liujilong

JavaScript

const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'

class MyPromise {
  constructor(executor) {
    try {
      executor(this._resolve, this._reject)
    } catch (e) {
      this._reject(e)
    }
  }

  state = PENDING
  result = undefined
  reason = ''
  fulfilledCallbacks = []
  rejectedCallbacks = []

  _resolve = value => {
    if (this.state !== PENDING) return
    this.state = FULFILLED
    this.result = value
    this.fulfilledCallbacks.forEach(cb => cb())
  }

  _reject = reason => {
    if (this.state !== PENDING) return
    this.state = REJECTED
    this.reason = reason
    this.rejectedCallbacks.forEach(cb => cb())
  }

  then(onFulfilled, onRejected) {
    onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value
    onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason }
    const self = this
    const promise2 = new MyPromise((resolve, reject) => {
      if (self.state === FULFILLED) {
        setTimeout(() => {
          try {
            const res = onFulfilled(self.result)
            self._resolvePromise(promise2, res, resolve, reject)
          } catch (e) {
            reject(e)
          }
        })
      } else if (self.state === REJECTED) {
        setTimeout(() => {
          try {
            const x = onRejected(self.reason)
            self._resolvePromise(promise2, x, resolve, reject)
          } catch (e) {
            reject(e)
          }
        })
      } else if (self.state === PENDING) {
        self.fulfilledCallbacks.push(() => {
          setTimeout(() => {
            try {
              const res = onFulfilled(self.result)
              self._resolvePromise(promise2, res, resolve, reject)
            } catch (e) {
              reject(e)
            }
          })
        })
        self.rejectedCallbacks.push(() => {
          setTimeout(() => {
            try {
              const x = onRejected(self.reason)
             ...