Promise.all的实现

125 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第20天,点击查看活动详情

promise.all的特点

接收一个Promise实例的数组或具有Iterator接口的对象 如果元素不是Promise对象,则使用Promise.resolve转成Promise对象 如果全部成功,状态变为resolved,返回值将组成一个数组传给回调 只有有一个失败,状态就变为rejected,返回值将直接传递给回调all()的返回值,也是新的promise对象

Promise.all(args)的用法和用途:

Promise.all(args)是一个方法来的,返回的是一个Promise实例,参数是一个数组,数组的每一项都是一个promise,等数组的每一项promise都成功resolve之后,Promise.all()才能resolve;如果有一个promise失败,那么Promise.all就会回调reject。

预备知识,判断Promise

const isPromise = function (promise) { return ( !!promise && (typeof promise === 'object' || typeof promise === 'function') && (typeof promise.then === 'function') ) }

注:使用两个感叹号,是将promise转成Boolean类型,再转回来,比较正规。

 入参:

此方法接受单个参数iterable,该参数采用promises数组或包含某些对象的普通数组。

返回值:

它遵循一些规则以返回单个承诺:

  • 如果传递的参数为空,则返回已解决的Promise。
  • 如果传递的iterable不包含诺言,它将返回异步解决的Promise。
  • 对于所有其他情况,它将返回一个未决的Promise。

代码实现

// all方法实现
function _all(promises) {
  return new Promise((resolve, reject) => {
    // 将 promises 转换成数组
    const promisesArr = Array.from(promises)
    // 创建一个数组,用来存放 promise 的结果
    const arr = []
    let count = 0
    const length = promisesArr.length
    for (let i = 0; i < length; i++) {
      // 循环 promisesArr 数组,每次取出一个 promise
      Promise.resolve(promisesArr[i]).then(o => {
        // 将每一个 promise 的结果放入数组
        arr.push(o)
        // 当数组的长度等于 promisesArr 的长度时,说明所有的 promise 都已经执行完毕
        if (++count === length) {
          // 全部执行完毕,成功抛出数组
          resolve(arr)
        }
        // 失败抛出错误,并终止
      }).catch(e => reject(e))
    }
  })
}

注:只要你会使用Promise,一步步的对着Promise.all的用法和介绍来实现,基本都能自己实现出来。每一步我都注释的挺详细的了,加油!-.-