前端面试之手写简易版promise实现

54 阅读1分钟
function myPromise (executor) {
  // 定义初始状态
  this.status = 'pending'
  // 保存异步操作的结果
  this.value = null
  // 保存异步失败的原因
  this.reason = ''
  // 成功任务队列
  this.onFullFilledCallback = []
  // 失败任务队列
  this.onRejectedCallback = []
  // 成功回调
  const resolve = (value) => {
    if (this.status !== 'pending') {
      return
    }
    this.status = 'fulfilled'
    this.value = value
    this.onFullFilledCallback.forEach(callback => callback())
  }
  // 失败回调
  const reject = (reason) => {
    if (this.status !== 'pending') {
      return
    }
    this.status = 'rejected'
    this.reason = reason
    this.onRejectedCallback.forEach(callback => callback())
  }
  // 立即执行函数
  try {
    executor(resolve, reject)
  } catch (error) {
    reject(error)
  }
}
// then 方法
myPromise.prototype.then = function (onFullfilled, onRejected) {
  const _promise = new myPromise((resolve, reject) => {
    if (this.status === 'fulfilled') {
      setTimeout(() => {
        try {
          const result = onFullfilled(this.value)
          resolve(reject)
        } catch (error) {
          reject(error)
        }
      })
    } else if (this.status === 'rejected') {
      setTimeout(() => {
        try {
          const result = onRejected(this.reason)
          resolve(result)
        } catch (error) {
          reject(error)
        }
      })
    } else {
      // 如果status还是pending,将回调加入队列
      this.onFullFilledCallback.push(() => {
        setTimeout(() => {
          try {
            const result = onFullfilled(this.value)
            resolve(result)
          } catch (error) {
            reject(error)
          }
        })
      })
      this.onRejectedCallback.push(() => {
        setTimeout(() => {
          try {
            const result = onRejected(this.reason)
            resolve(result)
          } catch (error) {
            reject(error)
          }
        })
      })
    }
  })
  return _promise
}

// 静态方法
myPromise.resolve = function (value) {
  return new myPromise(resolve => {
    resolve(value)
  })
}

myPromise.reject = function (resson) {
  return new myPromise((_, reject) => {
    reject(reason)
  })
}

// 测试一下

const promise = new myPromise((resolve, reject) => {
  setTimeout(() => {
    resolve('输出成功')
  }, 1000)
})

promise.then((value) => {
  console.log(value)
}, (reason) => {
  // 不会执行
})

内容有误还望大家留言指正