手写promise基础

105 阅读1分钟
class MyPromise {
  constructor(func) {
    //初始话值
    this.initStatus()
    //初始话this
    this.initBind()
    try {
      func(this.resolve, this.reject)
    } catch (error) {
      this.reject(error)
    }
  }
  initStatus() {
    this.PromiseResult = null
    this.PromiseState = 'pending'
    this.resolveCallbacks = []
    this.rejectCallbacks = []
  }
  initBind() {
    this.resolve = this.resolve.bind(this)
    this.reject = this.reject.bind(this)
  }
  resolve(res) {
    if (this.PromiseState !== 'pending') return
    this.PromiseState = 'fulfilled'
    this.PromiseResult = res
    this.resolveCallbacks.forEach((callback) => callback(res))
  }
  reject(err) {
    if (this.PromiseState !== 'pending') return
    this.PromiseState = 'rejected'
    this.PromiseResult = err
    this.rejectCallbacks.forEach((callback) => callback(err))
  }
  then(onFulfilled, onRejected) {
    onFulfilled =
      typeof onFulfilled === 'function' ? onFulfilled : (value) => value
    onRejected =
      typeof onRejected === 'function'
        ? onRejected
        : (err) => {
            throw err
          }
    // 生成需要返回的promise实例
    let thenPromise = new MyPromise((resolve, reject) => {
      const changePromise = (thenCallback) => {
        setTimeout(() => {
          try {
            const result = thenCallback(this.PromiseResult)
            if (result === thenPromise) {
              throw new Error('不能返回自己')
            }
            if (result instanceof MyPromise) {
              result.then(resolve, reject)
            } else {
              resolve(result)
            }
          } catch (error) {
            reject(err)
            throw new Error(error)
          }
        })
      }

      if (this.PromiseState === 'fulfilled') {
        changePromise(onFulfilled)
      } else if (this.PromiseState === 'rejected') {
        changePromise(onRejected)
      } else if (this.PromiseState === 'pending') {
        this.resolveCallbacks.push(changePromise.bind(this, onFulfilled))
        this.rejectCallbacks.push(changePromise.bind(this, onRejected))
      }
      return thenPromise
    })
  }
}