实现 Promise 原理

实现 Promise 原理 (实现部分常用方法)

  • Promise的方法
  1. resolove() 成功的回调函数, 参数为成功的返回值
  2. reject() 失败的回调函数, 参数为失败的返回值
  3. then() 链式调用 参数为 resolve() 和 reject() 回调函数
  4. all() all方法, 参数为数组, 全部执行完才输出执行结果, 返回值为数组
  5. race() race方法, 参数为数组(同all方法), 第一个执行完成,其他代码不再执行, 输出第一个执行结果
  6. catch() catch执行过程中一旦发生错误,便执行catch方法, 参数为 抓取的错误对象
  7. done()
  8. finally()
    // 微任务方法
    let nextTick = (function () {
      let callbacks = []
      let counter = 1
      function handler() {
        let copy = callbacks.slice()
        callbacks = []
        copy.forEach(cb => {
          cb()
        })
      }
      let node = document.createElement('div')
      let observer = new MutationObserver(handler)
      observer.observe(node, {
        childList: true
      })
      return function (cb) {
        callbacks.push(cb)
        // 触发 MutationObserver
        counter = (counter + 1) % 2
        node.innerHTML = counter // 当node节点内容发生变化就会触发 MutationObserver
      }
    })()
    // Promise实例有三个状态: pending , fulfilled, rejected
    const PENDING = 'pending'
    const FULFILLED = 'fulfilled'
    const REJECTED = 'rejected'
    class Promise2 {
      // 实现 Promise.all() 方法
      static all(promises) {
        return new this((resolve, reject) => {
          let promiseNum = promises.length
          let resolvedNum = 0
          let resolvedValues = new Array(promiseNum)
          for (let i = 0; i < promiseNum; i++) {
            this.resolve(promises[i]).then(
              // 成功的 resolve
              val => {
                resolvedNum++
                resolvedValues[i] = val
                // 所有的 Promise 都已经解决
                if (resolvedNum === promiseNum) {
                  resolve(resolvedValues)
                }
              },
              // 失败的 reject
              reason => {
                reject(reason)
              }
            )
          }
        })
      }
      // 实现 Promise.race() 方法
      static race(promises) {
        return new this((resolve, reject) => {
          let promisesLength = promises.length
          for (let i = 0; i < promisesLength; i++) {
            this.resolve(promises[i]).then(
              value => {
                resolve(value)
              },
              reason => {
                reject(reason)
              }
            )
          }
        })
      }
      // 实现 Promise.resolve() 方法
      static resolve(value) {
        if (value instanceof this) {
          return value
        }
        return new this((resolve, reject) => {
          resolve(value)
        })
      }
      // 实现 Promise.reject() 方法
      static reject(reason) {
        return new this((resolve, reject) => {
          reject(reason)
        })
      }
      constructor(executor) {
        this.status = PENDING
        this.value = null
        this.reason = null
        this.onFulfilledCallbacks = [] // 存储成功回调函数数组
        this.onRejectedCallbacks = [] // 存储失败回调函数数组
        // 成功的回调函数
        const resolve = (value) => {
          // this.constructor 指向构造函数 Promise2
          if (value instanceof this.constructor) {
            value.then(resolve, reject) // Promise2 解决后, 将外层的 Promise 也解决
            return
          }
          if (this.status === PENDING) {
            this.value = value
            this.status = FULFILLED
            nextTick(() => {
              // 遍历成功回调函数一一执行
              this.onFulfilledCallbacks.forEach(fn => {
                fn(this.value)
              })
            })
          }
        }
        // 失败的回调函数
        const reject = (reason) => {
          if (this.status === PENDING) {
            this.reason = reason
            this.status = REJECTED
            nextTick(() => {
              // 遍历失败回调函数一一执行
              this.onRejectedCallbacks.forEach((fn => {
                fn(this.reason)
              }))
            })
          }
        }
        try {
          executor(resolve, reject)
        } catch (e) {
          reject(e)
        }
      }
      // 实现then 的链式调用 (then 微任务执行回调函数)
      then(onFulfilled, onRejected) {
        const p2 = new this.constructor((resolve, reject) => {
          // 状态为 FULFILLED 时, 调用成功的回调函数
          if (this.status === FULFILLED) {
            nextTick(() => {
              try {
                let callbackValue = onFulfilled(this.value)
                resolve(callbackValue)
              } catch (error) {
                reject(error)
              }
            })
          }
          // 状态为 REJECTED 时, 调用失败的回调函数
          if (this.status === REJECTED) {
            nextTick(() => {
              try {
                let callbackValue = onRejected(this.reason)
                resolve(callbackValue)
              } catch (error) {
                reject(error)
              }
            })
          }
          // 状态为 PENDING 时, 存储成功 和 失败的回调函数
          if (this.status === PENDING) {
            // 存储成功的回调函数
            this.onFulfilledCallbacks.push(() => {
              try {
                let callbackValue = onFulfilled(this.value)
                resolve(callbackValue)
              } catch (error) {
                reject(error)
              }
            })
            // 存储失败的回调函数
            this.onRejectedCallbacks.push(() => {
              try {
                let callbackValue = onRejected(this.reason)
                resolve(callbackValue)
              } catch (error) {
                reject(error)
              }
            })
          }
        })
        return p2
      }
      // 实现 Promise.catch() 方法
      catch(onRejected) {
        return this.then(null, onRejected)
      }
    }
    // 实现done
    Promise2.prototype.done = function (onFulfilled, onRejected) {
      this.then(onFulfilled, onRejected)
        .catch(function (reason) {
          setTimeout(() => {
            throw reason
          })
        })
    }
    // 实现 finally
    Promise2.prototype.finally = function (callback) {
      let p = this.constructor
      return this.then(
        value => p.resolve(callback()).then(() => value),
        reason => p.resolve(callback())).then(() => { throw reson })
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值