自定义Promise构造函数的模块_IIFE定义模块

143 阅读3分钟

自定义的一个Promise,希望对大家对Promise的理解有所帮助,将整体复制到编辑器中效果更佳

(function (window) {

/* Promise构造函数 excutor: 执行器函数 (resolve, reject) => {} */

function Promise(excutor) {

const self = this // 保存promise对象
self.status = 'pending' // 初始化promise对象状态属性: pending代表未确定的
self.data = undefined // 初始化promise的用来存储数据的属性: undefined代表结果数据不确定
self.callbacks = [] // 用来保存待处理的成功与失败回调函数的数组容器


/* 
指定promise的成功结果和成功数据
1. 指定状态为成功: resolved
2. 指定数据为成功的value
3. 异步执行所有待处理的成功回调函数
*/
function resolve(value) {
  // 如果当前状态不是pending, 直接结束
  if (self.status!=='pending') {
    return
  }

  // 1. 指定状态为成功: resolved
  self.status = 'resolved'
  // 2. 指定数据为成功的value
  self.data = value
  // 3. 立即异步执行所有待处理的成功回调函数
  if (self.callbacks.length>0) {
    setTimeout(() => {
      self.callbacks.forEach(callbackObj => {
        callbackObj.onResolved(value)
      })
    })
  }
}

/* 
指定promise为失败结果和失败原因
1. 指定状态为失败: rejected
2. 指定数据为失败的reason
3. 异步执行所有待处理的失败回调函数
*/
function reject(reason) {

  // 如果当前状态不是pending, 直接结束
  if (self.status !== 'pending') {
    return
  }

  // 1. 指定状态为失败: rejected
  self.status = 'rejected'
  // 2. 指定数据为失败的reason
  self.data = reason
  // 3. 异步执行所有待处理的失败回调函数
  if (self.callbacks.length>0) {
    setTimeout(() => {
      self.callbacks.forEach(callbackObj => callbackObj.onRejected(reason))
    });
  }
}

try {
  // 立即同步执行执行器函数
  excutor(resolve, reject)
} catch (error) { // 一旦捕获到异常, 当前promise变为失败
  reject(error)
}

}

/* then() 方法返回一个新的 Promise。 它最多需要有两个参数: Promise 的成功和失败情况的回调函数。 绑定成功或失败回调函数 */ Promise.prototype.then = function (onResolved, onRejected) { const self = this const status = this.status

// 如果onResolved没有指定为函数, 直接将接收到的value传递给新的promise
onResolved = typeof onResolved === 'function' ? onResolved : value => value 

// 如果onRejected没有指定为函数,直接将接收的reason抛出让新的promise进入失败
onRejected = typeof onRejected === 'function' ? onRejected : reason => {throw reason}


return new Promise((resolve, reject) => {
  /* 
  执行成功/失败的回调函数, 根据执行的结果来指定新的promise的结果
  */
  function handle(callback) {
    try {
      const result = callback(self.data)
      // 如果回调函数执行的结果为promise对象
      // 将这个promise对象的结果为新的promise对象的结果
      if (result instanceof Promise) {          
        result.then(resolve, reject)       
      } else {
        resolve(result)
      }
    } catch (error) {
      reject(error)
    }
  }

  if (status === 'resolved') { // 当前promise已经成功了
    // 立即异步调用onResolved
    setTimeout(() => {
      handle(onResolved)
    })
  } else if (status === 'rejected') { // 当前promise已经失败了
    // 立即异步调用onRejected
    setTimeout(() => {
      handle(onRejected)
    })
  } else { 
    // 当前promise的结果还未确定
    // 将2个回调函数保存到callbacks
    /* self.callbacks.push({
      onResolved,
      onResjected
    }) */
    self.callbacks.push({
      onResolved(value) {
        handle(onResolved)
      },
      onRejected(reason) {
        handle(onRejected)
      }
    })
  }
})

}

/* catch() 方法返回一个Promise, 并且处理拒绝的情况。 它的行为与调用Promise.prototype.then(undefined, onRejected) 相同 */ Promise.prototype.catch = function (onRejected) { return this.then(undefined, onRejected) }

/* 返回一个以给定值解析后的Promise 对象 / Promise.resolve = function (value) { return new Promise ((resolve, reject) => { // 如果value是promise, 将这个promise结果作为新的promise的结果 if (value instanceof Promise) { / value.then( value => { resolve(value) }, reason => { reject(reason) } ) */ value.then(resolve, reject) } else { resolve(value) } }) }

/* 返回一个带有拒绝原因reason参数的Promise对象 */ Promise.reject = function (reason) { return new Promise((resolve, reject) => { reject(reason) }) }

/* 返回一个Promise对象, 只有当所有的promise都成功才最终成功(成功值是values数组), 只要有一个promise失败了最终就直接失败(失败的原因为reason) */

Promise.all = function (promises) {

let resolvedCount = 0 // 保存已成功的个数
const values = new Array(promises.length)

return new Promise((resolve, reject) => {

  for (let i = 0; i < promises.length; i++) {
    const p = promises[i]
     Promise.resolve(p).then(
       value => {
         // 每成功一个增加1
         resolvedCount++
         // 将当前value保存到values
         values[i] = value

         // 全部都成功了, 新的promise就成功了
         if (resolvedCount === promises.length) {
           resolve(values)
         }
       },
       reason => { // 当前的promise失败了
         reject(reason) // 新的promise直接失败了
       }
     )
  }
})

}

/* 返回一个Promise对象, 只要有一个promise有了结果, 这个结果就是最终的结果, */

Promise.race = function (promises) { return new Promise((resolve, reject) => { promises.forEach(p => { Promise.resolve(p).then( value => resolve(value), reason => reject(reason), ) }) }) }

// 暴露Promise

window.Promise = Promise

})(window)