实现一个Promise

286 阅读1分钟
/**
 * 自定义Promise函数模块:IIFE
 */
(function (window) {
  /**
   * Promise构造函数
   * @param {*} excutor 执行器函数,函数参数为onResolved和onRejected两个函数
   */
  function Promise(excutor) {
    this.status = "pending"
    this.data = undefined
    this.callbacks = []
    const that = this
    // excutor是用户定义的逻辑,我们通过参数传递一个函数进去,就能从内部去操作他的结果了
    function resolve(value) {
      if (that.status !== 'pending') return false
      that.status = 'resolved'
      that.data = value
      if (that.callbacks.length > 0) {
        setTimeout(() => {
          that.callbacks.forEach(callbacksObj => {
            callbacksObj.onResolved(that.data)
          });
        });
      }
    }
    function reject(reason) {
      if (that.status !== 'pending') return false
      that.status = 'rejected'
      that.data = reason
      if (that.callbacks.length > 0) {
        setTimeout(() => {
          that.callbacks.forEach(callbacksObj => {
            callbacksObj.onRejected(that.data)
          });
        });
      }

    }
    try {
      excutor(resolve, reject)
    } catch (error) { // 如果执行器函数抛出异常,promise也是失败
      reject(error)
    }
  }
  // 原型上的then方法,实例调用,不能直接调用,要等excutor回调函数执行结果出来之后调用
  Promise.prototype.then = function (onResolved, onRejected) {

    onResolved=typeof onRejected==="function"?onRejected:value=>value
    onRejected=typeof onRejected==="function"?onRejected:reason=>{throw reason}
    let that=this
    // 封装函数
    // 为了链式调用连续.then,要返回一个新的promise,后一个.then获取的结果由前一个onResolved函数的结果决定
    return new Promise((resolve, reject) => {
        function handle(callback) {
          try {
            let res=callback(that.data)
            if (res instanceof Promise) {
              res.then(resolve, reject)
            } else {
              resolve(res)
            }
          } catch (error) {
            reject(error)
          }
        }
      if (that.status === "pending") {
        // this.callbacks.push({ onResolved, onRejected }) // 光push不行,还要在里面改promise的状态
        that.callbacks.push({ 
          onResolved(value){
            handle(onResolved)
          }, 
          onRejected(reason){
            handle(onRejected)
            
          } 
        }) 

      } else if (that.status === "resolved") {
        setTimeout(() => {
          //判断res的类型
          /**
           * 1.如果是抛出的异常,就要catch接收到,并让这个return的promise失败
           * 2.如果是return一个promise,要跟据这个promise的结果来决定
           * 3.如果不是一个promise,那函数返回值就是这个promise的值
           */
          handle(onResolved)
        });
      } else {
        setTimeout(() => {
          handle(onRejected)
        });
      }



    })
  }
  // 原型上的catch方法
  Promise.prototype.catch = function (onRejected) {
    return this.then(undefined,onRejected)
  }
  // 函数对象方法reslove,直接通过Promise.resolve()调用,个人认为类似一个语法糖
  Promise.resolve = function (value) {
    new Promise((resolve, reject) => {
      resolve(value)
    })
  }
  // 函数对象方法rejected
  Promise.rejected = function (reason) {

  }
  // 函数对象方法all
  Promise.all = function (promises) {

  }
  // 函数对象方法race
  Promise.race = function (promises) {

  }

  // 向外暴露Promise函数
  window.Promise = Promise
})(window)