微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

手写Promise.all

一、Pormise.all

接受一个Promise对象组成的数组返回一个新的Promise,只有所有的Promise都成功才成功,只要有一个失败了就直接失败。成功的结果是每个Promise成功结果组成的数组失败的结果是Promise数组中失败的结果

  • 传入一个 Iterable,但大部分情况下是数组,以下以数组代替
  • 传入一个数组,其中可包含 Promise,也可包含普通数据
  • 数组中 Prmise 并行执行
  • 但凡有一个 Promise 被 Reject 掉,Promise.all 失败
  • 保持输出数组位置与输入数组一致
  • 所有数据 resolve 之后,返回结果

二、实现

function pAll (_promises) {
  return new Promise((resolve, reject) => {
    // Iterable => Array
    const promises = Array.from(_promises)
    // 结果用一个数组维护
    const res = []
    const len = promises.length
    let count = 0
    for (let i = 0; i < len; i++) {
      // Promise.resolve 确保把所有数据都转化为 Promise
      Promise.resolve(promises[i]).then(result=> { 
        // 因为 promise 是异步的,保持数组一一对应
        // 如果参数是 Promise 实例,那么Promise.resolve将不做任何修改、原封不动地返回这个实例。
        res[i] = result;
        // 如果数组中所有 promise 都完成,则返回结果数组
        if (++count === len) {
          resolve(res)
        }
        // 当发生异常时,直接 reject
      }).catch(err => reject(err))
    }
  })
}

其中有几个点:

  • Array.from()方法就是将一个类数组对象或者可遍历对象转换成一个真正的数组。
  • Promise.resolve 确保把所有数据都转化为 Promise,如果参数是 Promise 实例,那么Promise.resolve将不做任何修改原封不动地返回这个实例

参考:https://github.com/shfshanyue/Daily-Question/issues/500

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐