其他分享
首页 > 其他分享> > 浅浅手撕promise

浅浅手撕promise

作者:互联网

一、前言

模型压缩那块,还没琢磨明白就先不更,今天小更一下手撕promise,给小伙伴看个乐。

二、如何实现promise

知己知彼,才能百战百胜,我们先需要知道promise是什么,原理是什么,才能去实现这个过程。

1、promise是什么

说白了就是一种异步的解决方案,从语法上而言,promise就是一个对象,但这里面存放着一个未来将会执行的结果,这样可以有效解决回调地狱(俄罗斯套娃,异步套异步)。

promise一共就三种状态

pending(等待态)fulfiled(成功态)rejected(失败态)

整个过程就是,pending 状态的 Promise 对象会触发 fulfilled或者rejected 状态,在其状态处理方法resolve或者reject方法中可以传入参数或者失败信息。当操作成功完成时,Promise 对象的 then 方法就会被调用;否则就会触发 catch方法。

当然还有一个合并全部异步状态的Promise.all(), 和对应的拒绝方法Promise.race

2、实现过程

先将整个方法搭建出来

(function name(window) {
    function Promise(excutor) {
    }
  // 向外暴露 Promise 函数
  window.Promise = Promise
})(window)
复制代码

然后往里面完善一下promise函数的逻辑,里面应该有resolve和reject方法,并且要捕捉是否出错,出错就是reject抛出error信息。

function Promise(excutor) {
    // excutor带参,同步执行resolve和reject方法,出错就用reject抛出异常
    function resolve(value) {

    }

    function reject(reason) {

    }

    try {
      excutor(resolve, reject)
    } catch (error) {
      reject(error)
    }
}
复制代码

随后就是外层的then和catch方法了,then是正常执行的情况,catch就捕捉异常并上报。这里也是因为reject已经抛出异常,外层catch也自然能接受到。

Promise.prototype.then = function(onResolved, onRejected) {

}

Promise.prototype.catch = function(onRejected) {

}
复制代码

上面只是定义了函数的壳子,还需要额外调用promise下的函数,去返回对应状态的promise。

   /**
   * @func Promise 函数对象的 resolve()
   * @param value 成功的回调函数
   * @returns 返回一个指定结果 value 的成功的 Promise
   */
  Promise.resolve = function(value) {

  }

  /**
   * @func Promise 函数对象的 reject()
   * @param reason 失败的回调函数
   * @returns 返回一个指定结果 reject 的失败的 Promise
   */
  Promise.reject = function(reason) {
  
  }
复制代码

上述添加完整之后,基本结构已经搭建完毕,不过还有额外的多个promise合并处理的all方法和race方法。

/**
   * Peomise 函数对象的 all()
   * @param promises 请求数组
   * @returns 返回一个 Promise
   * @returns 只有 Promise 都成功时才成功,只要有一个失败就失败,并返回失败的 Promise
   */
  Promise.all = function(promises) {

  }

  /**
   * Peomise 函数对象的 race()
   * @param promises 请求数组
   * @returns 返回一个 Promise,其结果由第一个完成的 Promise 决定
   */
  Promise.race = function(promises) {

  }
复制代码

整体结构就写好了,接下来就具体完善下各个函数的逻辑,一个promise就诞生了。

下面附完整代码

/**
 * 自定义 Promise 函数模块
 */
(function name(window) {
  // 定义promise中的三种状态
  const STATUS_PENDING = 'pending'
  const STATUS_FULFILLED = 'fulfilled'
  const STATUS_REJECTED = 'rejected'
  function Promise(excutor) {
    // excutor带参,同步执行resolve和reject方法,出错就用reject抛出异常
    // 初始化该class中的初始状态
    this.status = STATUS_PENDING
    // 定义class中成功(value)和失败(err)时的变量值
    this.value = ''
    this.err = ''

// promis异步中最重要的异步,定义成功和错误函数存储的数组,存放异步时还没有执行的操作
this.onResCallbacks = []
this.onErrCallbacks = []
function resolve(value) {
  // 首先判断该class中的状态,只有状态为pending时才能转化class转态为fulfilled或者rejected
  if (this.status === STATUS_PENDING) {
    // 修改class的转态为fulfilled,也就表示不会转进行其他转态的转化了
    this.status = STATUS_FULFILLED
    // 将成功(resolve)状态下的值赋给class的成功返回res
    this.value = value
    // 此时状态由pending转为fulfilled,执行之前在then中存放的需要执行的异步操作,promise的then中参数res接受结果
    this.onResCallbacks.forEach((fn) => {
      fn()
    })
  }
}

function reject(reason) {
  // 首先判断该class中的状态,只有状态为pending时才能转化class转态为fulfilled或者rejected
  if (this.status === STATUS_PENDING) {
    // 修改class的转态为rejected,也就表示不会转进行其他转态的转化了
    this.status = STATUS_REJECTED
    // 将失败(reject)状态下的值赋给class的失败返回err
    this.err = reason
    // 此时状态由pending转为rejected,执行之前在catch中存放的需要执行的异步操作,promise的catch中参数err接受结果
    this.onErrCallbacks.forEach((fn) => {
      fn()
    })
  }
}

try {
  excutor(resolve, reject)
} catch (error) {
  reject(error)
}
  }

  Promise.prototype.then = function(onResolved, onRejected) {
    // 如果是异步的,此时在constructor中status的状态还没变成fulfilled,所以会跳过onRes调用,没有返回
    if (this.status === STATUS_FULFILLED) {
      onResolved(this.res)
    }
    // 但是我们将此时的异步放入数组存放
    if (this.status === STATUS_PENDING) {
      this.onResCallbacks.push(() => onResolved(this.res))
    }
    // 这步操作保证了then和catch能够在同级一起"."调起,当then上述操作完后,返回class实例,便可以接在后面继续调用catch
    return this
  }

  Promise.prototype.catch = function(onRejected) {
    // 如果是异步的,此时在constructor中status的状态还没变成rejected,所以会跳过onErr调用,没有返回
    if (this.status === STATUS_REJECTED) {
      onRejected(this.err)
    }
    // 但是我们将此时的异步放入数组存放
    if (this.status === STATUS_PENDING) {
      this.onErrCallbacks.push(() => onRejected(this.err))
    }
    // 这步操作保证了then和catch能够在同级一起"."调起,当catch上述操作完后,返回class实例,便可以接在后面继续调用then
    return this
  }
  /**
   * @func Promise 函数对象的 resolve()
   * @param value 成功的回调函数
   * @returns 返回一个指定结果 value 的成功的 Promise
   */
  Promise.resolve = function(value) {
    if (value instanceof Promise) return value
    return new Promise(resolve => resolve(value))
  }

  /**
   * @func Promise 函数对象的 reject()
   * @param reason 失败的回调函数
   * @returns 返回一个指定结果 reject 的失败的 Promise
   */
  Promise.reject = function(reason) {
    if (reason instanceof Promise) return reason
    return new Promise(reject => (reason))
  }
  /**
   * Peomise 函数对象的 all()
   * @param promises 请求数组
   * @returns 返回一个 Promise
   * @returns 只有 Promise 都成功时才成功,只要有一个失败就失败,并返回失败的 Promise
   */
  Promise.all = function(promises) {
    return new Promise((resolve, reject) => {
      const arr = []
      let index = 0 // 解决多个异步的并发问题,要使用计数器
      function promiseAdd(key, value) {
        arr[key] = value
        if (++index === promises.length) {
          resolve(arr)
        }
      }
      for (let i = 0; i < promises.length; i++) {
        const current = promises[i]
        if (current instanceof Promise) {
          current.then((data) => {
            promiseAdd(i, data)
          }, reject)
        } else {
          promiseAdd(i, current)
        }
      }
    })
  }

  /**
   * Peomise 函数对象的 race()
   * @param promises 请求数组
   * @returns 返回一个 Promise,其结果由第一个完成的 Promise 决定
   */
  Promise.race = function(promises) {
    return new Promise((resolve, reject) => {
      for (const value of promises) {
        this.resolve(value).then(res => {
          resolve(res)
        }, err => {
          reject(err)
        })
      }
    })
  }
  // 向外暴露 Promise 函数
  window.Promise = Promise
})(window)
复制代码

ps: 简单整理了一下,如有错误还请指正。

Snipaste_2022-07-19_15-30-26.jpg


作者:地霊殿__三無
链接:https://juejin.cn/post/7128847180026085389
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

标签:function,resolve,浅浅,value,Promise,reject,promise
来源: https://www.cnblogs.com/Earth-Hall-Sanwu/p/16673012.html