@toc

代码见https://github.com/yk2012/Promise_demo (opens new window)

# 1. 整体结构框架

/**
 * 自定义Promise函数模块:IIFE
 */
(function (window) {
  const PENDING = 'pending'
  const RESOLVED = 'fulfilled'
  const REJECTED = 'rejected'

  /**
   * Promise构造函数
   * @param {function} executor 执行器函数(同步执行)(resolve, reject) => {}
   */
  function Promise(executor) {
  
  }

  /**
   * Promise原型对象then方法 
   * 指定成功和失败的回调函数
   * @param {function} onResolved 成功的回调函数(value) => {}
   * @param {function} onRejected 失败的回调函数(reason) => {}
   * @returns 一个新的promise对象结果由onResolved/onRejected执行的结果决定
   */
  Promise.prototype.then = function (onResolved, onRejected) {
    
  }

  /**
   * Promise原型对象catch方法
   * 指定失败的回调函数
   * @param {function} onRejected 失败的回调函数(reason) => {}
   * @returns 一个新的promise对象
   */
  Promise.prototype.catch = function (onRejected) {
    
  }

  /**
   * Promise函数对象resolve方法
   * @param {*} value 成功的值
   * @returns 一个成功/失败的promise
   */
   Promise.resolve = function (value) {

  }

  /**
   * Promise函数对象reject方法
   * @param {*} resaon 失败的原因
   * @returns 一个失败的promise
   */
  Promise.reject = function (resaon) {

  }

  /**
   * Promise函数对象all方法
   * @param {Array<Promise>} promises 
   * @returns 一个promise,只有当所有promise都成功时才成功,否则只要有一个失败就失败
   */
  Promise.all = function (promises) {

  }

  /**
   *Promise函数对象race方法
   * @param {Array<Promise>} promises 
   * @returns 返回 一个promise,其结果由第一个完成的promise决定
   */
  Promise.race = function (promises) {

  }


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

# 2. Promise(executor)

  • Promise构造函数
  • executor: 执行器函数(同步执行)
/**
 * Promise构造函数
 * @param {*} executor 执行器函数(同步执行)(resolve, reject) => {}
 */
function Promise(executor) {

  const self = this; // 保存当前实例对象的this的值
  // 添加属性
  self.PromiseState = PENDING // 给promise对象指定status属性,初始值为pending
  self.PromiseResult = null // 给promise对象指定一个用于存储结果数据的属性
  self.callbacks = [] // 存的是对象 每个元素的结构:{onResolved() {}, onRejected() {}}

  /**
   * executor内部定义成功时调用的函数
   * @param {*} value 成功的值
   * @returns 
   */
  function resolve(value) {
    // 如果当前状态不是pending,直接结束
    if (self.PromiseState !== PENDING) return
    // 1. 修改对象的状态(promiseState)为 fulfilled
    self.PromiseState = RESOLVED 
    // 2. 设置对象结果值(promiseResult)为 value
    self.PromiseResult = value
    // 如果有待执行的callback函数,立即【异步】执行回调函数onResolved
    if (self.callbacks.length > 0) {
      setTimeout(() => { // 放入队列中执行所有成功的回调
        self.callbacks.forEach(callbacksObj => {
          callbacksObj.onResolved(value)
        })
      }, 0)
    }
  }
  
  /**
   * executor内部定义失败时调用的函数
   * @param {*} reason 失败的原因
   * @returns 
   */
  function reject(reason) {
    // 如果当前状态不是pending,直接结束
    if (self.PromiseState !== PENDING) return
    // 1. 修改对象的状态(promiseState)为 rejected
    self.PromiseState = REJECTED
    // 2. 设置对象结果值(promiseResult)为 reason
    self.PromiseResult = reason
    // 如果有待执行的callback函数,立即【异步】执行回调函数onRejected
    if (self.callbacks.length > 0) {
      setTimeout(() => { // 放入队列中执行所有失败的回调
        self.callbacks.forEach(callbacksObj => {
          callbacksObj.onRejected(reason)
        })
      }, 0)
    }
  }
  
  // 立即【同步】执行executor函数
  try {
    executor(resolve, reject)
  } catch(error) { // 如果执行器抛出异常,promise对象变成rejected状态
    reject(error)
  }
}

# 3. Promise.prototype.then

Promise.prototype.then = function (onResolved, onRejected) {
  const self = this
  return new Promise((resolve, reject) => {
    if (self.PromiseState === PENDING) { // 假如当前状态还是pending状态,将回调函数保存起来
      self.callbacks.push({
        onResolved(value) {
          // onResolved(self.PromiseResult)
          try {
            const result = onResolved(self.PromiseResult) // 执行成功的回调 result接收返回值
            if (result instanceof Promise) { // 3. 如果回调函数返回的是promise
              // result.then(
              //   value => {
              //     resolve(value) // 当result成功时,让return的promise也成功
              //   },
              //   reason => {
              //     reject(reason) // 当result失败时,让return的promise也失败
              //   }
              // )
              result.then(resolve, reject) // 简洁写法
            } else { // 2. 如果回调函数返回的不是promise
              resolve(result)
            }
          } catch (error) { //1. 如果抛出异常
            reject(error)
          }
         },
        onRejected(reason) {
          // onRejected(self.PromiseResult)
          try {
            const result = onRejected(self.PromiseResult) // 执行失败的回调 result接收返回值
            if (result instanceof Promise) { // 3. 如果回调函数返回的是promise
              result.then(resolve, reject)
            } else { // 2. 如果回调函数返回的不是promise
              resolve(result)
            }
          } catch (error) { //1. 如果抛出异常
            reject(error)
          }
         }
      })
    } else if (self.PromiseState === RESOLVED) { // resolved
      setTimeout(() => {
        /**
         * 1. 如果抛出异常,return的promise就会失败,reason是error
         * 2. 如果回调函数返回的不是promise,return的promise就会成功,value就是返回的值
         * 3. 如果回调函数返回的是promise,return的promise结果就是这个promise的结果
         */
        try {
          const result = onResolved(self.PromiseResult) // 执行成功的回调 result接收返回值
          if (result instanceof Promise) { // 3. 如果回调函数返回的是promise
            // result.then(
            //   value => {
            //     resolve(value) // 当result成功时,让return的promise也成功
            //   },
            //   reason => {
            //     reject(reason) // 当result失败时,让return的promise也失败
            //   }
            // )
            result.then(resolve, reject) // 简洁写法
          } else { // 2. 如果回调函数返回的不是promise
            resolve(result)
          }
        } catch (error) { //1. 如果抛出异常
          reject(error)
        }
      }, 0)
    } else { // rejected
      setTimeout(() => {
        try {
          const result = onRejected(self.PromiseResult) // 执行失败的回调 result接收返回值
          if (result instanceof Promise) { // 3. 如果回调函数返回的是promise
            result.then(resolve, reject)
          } else { // 2. 如果回调函数返回的不是promise
            resolve(result)
          }
        } catch (error) { //1. 如果抛出异常
          reject(error)
        }
      }, 0)
    }
  })
}

简化封装一下

/**
 * Promise原型对象then方法 
 * 指定成功和失败的回调函数
 * @param {function} onResolved 成功的回调函数(value) => {}
 * @param {function} onRejected 失败的回调函数(reason) => {}
 * @returns 一个新的promise对象结果由onResolved/onRejected执行的结果决定
 */
Promise.prototype.then = function (onResolved, onRejected) {
  // 指定默认的成功的回调onResolved (向后传递成功的value)
  onResolved = typeof onResolved === 'function' ? onResolved : value => value
  // 指定默认的失败的回调onRejected(向后传递失败的reason 实现错误/异常传透的关键点)
  onRejected = typeof onRejected === 'function' ? onRejected : reason => {throw reason}

  const self = this

  return new Promise((resolve, reject) => {
    /**
     * 调用指定回调函数处理,根据执行的结果改变return的promise的状态
     * @param {function} callback 指定回调函数
     */
    function handle(callback) {
      try {
        const result = callback(self.PromiseResult) // result获取回调函数执行(return)的结果
        if (result instanceof Promise) { // 3. 如果回调函数返回的是promise
          result.then(resolve, reject) // 简洁写法
        } else { // 2. 如果回调函数返回的不是promise
          resolve(result)
        }
      } catch (error) { //1. 如果抛出异常
        reject(error)
      }
    }

    if (self.PromiseState === PENDING) { // 1. 当前状态是pending状态,将回调函数保存起来
      self.callbacks.push({
        onResolved(value) { //执行成功的回调函数,改promise的状态
          handle(onResolved)
         },
        onRejected(reason) { //执行失败的回调函数,改promise的状态
          handle(onRejected)
         }
      })
    } else if (self.PromiseState === RESOLVED) { // 2. resolved,【异步】执行onResolved并改变return的promise的状态
      setTimeout(() => {
        handle(onResolved)
      }, 0)
    } else { // 3. rejected,【异步】执行onRejected并改变return的promise的状态
      setTimeout(() => {
        handle(onRejected)
      }, 0)
    }
  })
}

# 4. Promise.prototype.catch

/**
 * Promise原型对象catch方法
 * 指定失败的回调函数
 * @param {function} onRejected 失败的回调函数(reason) => {}
 * @returns 一个新的promise对象
 */
Promise.prototype.catch = function (onRejected) {
  return this.then(undefined, onRejected)
}

# 5. Promise.resolve

/**
 * Promise函数对象resolve方法
 * @param {*} value 成功的值
 * @returns 一个成功/失败的promise
 */
Promise.resolve = function (value) {
  // 返回一个成功/失败的promise
  return new Promise((resolve, reject) => {
    if (value instanceof Promise) { // value是promise => 使用value的结果作为promise的结果
      value.then(resolve,reject)
    } else { // value不是promise => promise状态变为成功,数据是value
      resolve(value)
    }
  })
}

# 6. Promise.reject

/**
 * Promise函数对象reject方法
 * @param {*} resaon 失败的原因
 * @returns 一个失败的promise
 */
Promise.reject = function (reason) {
  // 返回一个失败的promise
  return new Promise((resolve, reject) => {
    reject(reason)
  })
}

# 7. Promise.all

/**
 * Promise函数对象all方法
 * @param {Array<Promise>} promises 
 * @returns 一个promise,只有当所有promise都成功时才成功,否则只要有一个失败就失败
 */
Promise.all = function (promises) {
  return new Promise((resolve, reject) => {
    let count = 0 // 声明计数变量
    // const values = []; // 保存每个成功promise结果的数组
    const values = new Array(promises.length) // 指定数组长度
    for (let i = 0; i < promises.length; i++){
      // promises[i].then(value => {
      Promise.resolve(promises[i]).then(value => { // 防止数组中有不是promise的元素
        // 得知对象状态是成功
        count++
        // 将当前promise对象成功的结果存入到数组中
        values[i] = value
        if (count === promises.length) { //每个promise对象都成功
          resolve(values) // 修改函数状态
        }
      }, reason => {
          reject(reason)
        })
    }
  })
}

# 8. Promise.race

/**
 *Promise函数对象race方法
 * @param {Array<Promise>} promises 
 * @returns 返回 一个promise,其结果由第一个完成的promise决定
 */
Promise.race = function (promises) {
  return new Promise((resolve, reject) => {
    for (let i = 0; i < promises.length; i++){
      // promises[i].then(value => {
      Promise.resolve(promises[i]).then(value => { // 防止数组中有不是promise的元素
        // 修改返回对象的状态为 成功
        resolve(value)
      }, reason => {
        reject(reason)
      })
    }
  })
}

# 9. 自定义函数对象方法Promise.resolveDelay&Promise.rejectDelay

/**
 * 自定义方法 延时返回一个成功/失败的promise
 * @param {*} value 成功的数据
 * @param {Number} timeout 延迟时间
 * @returns 一个成功/失败的promise
 */
Promise.resolveDelay = function (value, timeout) {
  // 延时返回一个成功/失败的promise
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (value instanceof Promise) { // value是promise => 使用value的结果作为promise的结果
        value.then(resolve,reject)
      } else { // value不是promise => promise状态变为成功,数据是value
        resolve(value)
      }
    })
  }, timeout);
}

/**
 * 自定义方法 延时返回一个失败的promise
 * @param {*} reason 失败的原因
 * @param {*} timeout 延迟时间
 * @returns 一个失败的promise
 */
Promise.rejectDelay = function (reason, timeout) {
  // 延时返回一个失败的promise
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      reject(reason)
    }, timeout)
  })
}

# 10. class写法

/**
 * 自定义Promise函数模块:IIFE
 */
(function (window) {

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

  class Promise {
    /**
     * Promise构造函数
     * @param {function} executor 执行器函数(同步执行)(resolve, reject) => {}
     */
    constructor(executor) {

      const self = this; // 保存当前实例对象的this的值
      // 添加属性
      self.PromiseState = PENDING // 给promise对象指定status属性,初始值为pending
      self.PromiseResult = null // 给promise对象指定一个用于存储结果数据的属性
      self.callbacks = [] // 存的是对象 每个元素的结构:{onResolved() {}, onRejected() {}}

      /**
       * executor内部定义成功时调用的函数
       * @param {*} value 成功的值
       * @returns 
       */
      function resolve(value) {
        // 如果当前状态不是pending,直接结束
        if (self.PromiseState !== PENDING) return
        // 1. 修改对象的状态(promiseState)为 fulfilled
        self.PromiseState = RESOLVED
        // 2. 设置对象结果值(promiseResult)为 value
        self.PromiseResult = value
        // 如果有待执行的callback函数,立即【异步】执行回调函数onResolved
        if (self.callbacks.length > 0) {
          setTimeout(() => { // 放入队列中执行所有成功的回调
            self.callbacks.forEach(callbacksObj => {
              callbacksObj.onResolved(value)
            })
          }, 0)
        }
      }
    
      /**
       * executor内部定义失败时调用的函数
       * @param {*} reason 失败的原因
       * @returns 
       */
      function reject(reason) {
        // 如果当前状态不是pending,直接结束
        if (self.PromiseState !== PENDING) return
        // 1. 修改对象的状态(promiseState)为 rejected
        self.PromiseState = REJECTED
        // 2. 设置对象结果值(promiseResult)为 reason
        self.PromiseResult = reason
        // 如果有待执行的callback函数,立即【异步】执行回调函数onRejected
        if (self.callbacks.length > 0) {
          setTimeout(() => { // 放入队列中执行所有失败的回调
            self.callbacks.forEach(callbacksObj => {
              callbacksObj.onRejected(reason)
            })
          }, 0)
        }
      }
    
      // 立即【同步】执行executor函数
      try {
        executor(resolve, reject)
      } catch (error) { // 如果执行器抛出异常,promise对象变成rejected状态
        reject(error)
      }
    }

    /**
     * Promise原型对象then方法 
     * 指定成功和失败的回调函数
     * @param {function} onResolved 成功的回调函数(value) => {}
     * @param {function} onRejected 失败的回调函数(reason) => {}
     * @returns 一个新的promise对象结果由onResolved/onRejected执行的结果决定
     */
    then (onResolved, onRejected) {
      // 指定默认的成功的回调onResolved (向后传递成功的value)
      onResolved = typeof onResolved === 'function' ? onResolved : value => value
      // 指定默认的失败的回调onRejected(向后传递失败的reason 实现错误/异常传透的关键点)
      onRejected = typeof onRejected === 'function' ? onRejected : reason => {throw reason}

      const self = this

      return new Promise((resolve, reject) => {
        /**
         * 调用指定回调函数处理,根据执行的结果改变return的promise的状态
         * @param {function} callback 指定回调函数
         */
        function handle(callback) {
          try {
            const result = callback(self.PromiseResult) // result获取回调函数执行(return)的结果
            if (result instanceof Promise) { // 3. 如果回调函数返回的是promise
              result.then(resolve, reject) // 简洁写法
            } else { // 2. 如果回调函数返回的不是promise
              resolve(result)
            }
          } catch (error) { //1. 如果抛出异常
            reject(error)
          }
        }

        if (self.PromiseState === PENDING) { // 1. 当前状态是pending状态,将回调函数保存起来
          self.callbacks.push({
            onResolved(value) { //执行成功的回调函数,改promise的状态
              handle(onResolved)
            },
            onRejected(reason) { //执行失败的回调函数,改promise的状态
              handle(onRejected)
            }
          })
        } else if (self.PromiseState === RESOLVED) { // 2. resolved,【异步】执行onResolved并改变return的promise的状态
          setTimeout(() => {
            handle(onResolved)
          }, 0)
        } else { // 3. rejected,【异步】执行onRejected并改变return的promise的状态
          setTimeout(() => {
            handle(onRejected)
          }, 0)
        }
      })
    }


    /**
     * Promise原型对象catch方法
     * 指定失败的回调函数
     * @param {function} onRejected 失败的回调函数(reason) => {}
     * @returns 一个新的promise对象
     */
    catch (onRejected) {
      return this.then(undefined, onRejected)
    }


    /**
     * Promise函数对象resolve方法
     * @param {*} value 成功的值
     * @returns 一个成功/失败的promise
     */
    static resolve(value) {
      // 返回一个成功/失败的promise
      return new Promise((resolve, reject) => {
        if (value instanceof Promise) { // value是promise => 使用value的结果作为promise的结果
          value.then(resolve,reject)
        } else { // value不是promise => promise状态变为成功,数据是value
          resolve(value)
        }
      })
    }


    /**
     * Promise函数对象reject方法
     * @param {*} resaon 失败的原因
     * @returns 一个失败的promise
     */
    static reject (reason) {
      // 返回一个失败的promise
      return new Promise((resolve, reject) => {
        reject(reason)
      })
    }

  
    /**
     * Promise函数对象all方法
     * @param {Array<Promise>} promises 
     * @returns 一个promise,只有当所有promise都成功时才成功,否则只要有一个失败就失败
     */
     static all (promises) {
      return new Promise((resolve, reject) => {
        let count = 0 // 声明计数变量
        // const values = []; // 保存每个成功promise结果的数组
        const values = new Array(promises.length) // 指定数组长度
        for (let i = 0; i < promises.length; i++){
          // promises[i].then(value => {
            Promise.resolve(promises[i]).then(value => { // 防止数组中有不是promise的元素
            // 得知对象状态是成功
            count++
            // 将当前promise对象成功的结果存入到数组中
            values[i] = value
            if (count === promises.length) { //每个promise对象都成功
              resolve(values) // 修改函数状态
            }
          }, reason => {
              reject(reason)
            })
        }
      })
    }


    /**
     *Promise函数对象race方法
    * @param {Array<Promise>} promises 
    * @returns 返回 一个promise,其结果由第一个完成的promise决定
    */
    static race (promises) {
      return new Promise((resolve, reject) => {
        for (let i = 0; i < promises.length; i++){
          // promises[i].then(value => {
          Promise.resolve(promises[i]).then(value => { // 防止数组中有不是promise的元素
            // 修改返回对象的状态为 成功
            resolve(value)
          }, reason => {
            reject(reason)
          })
        }
      })
    }

    /**
     * 自定义方法 延时返回一个成功/失败的promise
     * @param {*} value 成功的数据
     * @param {Number} timeout 延迟时间
     * @returns 一个成功/失败的promise
     */
    static resolveDelay (value, timeout) {
      // 延时返回一个成功/失败的promise
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          if (value instanceof Promise) { // value是promise => 使用value的结果作为promise的结果
            value.then(resolve,reject)
          } else { // value不是promise => promise状态变为成功,数据是value
            resolve(value)
          }
        })
      }, timeout);
    }

    /**
     * 自定义方法 延时返回一个失败的promise
     * @param {*} reason 失败的原因
     * @param {*} timeout 延迟时间
     * @returns 一个失败的promise
     */
     static rejectDelay (reason, timeout) {
      // 延时返回一个失败的promise
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          reject(reason)
        }, timeout)
      })
    }
  }

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

代码见https://github.com/yk2012/Promise_demo (opens new window)

上次更新: 2022/4/21 22:21:34