手写JavaScript中的Promise.all方法(JS中Promise.all的执行过程)

37 篇文章 1 订阅
3 篇文章 0 订阅

简介:

  • Promise.all是JavaScript中一种用于处理多个Promise对象的方法,该方法接收一个数组作为参数,并返回一个新的Promise对象。

  • 这个新的对象会在所有Promise对象都成功解析后解析,解析的结果是一个数组,包含了所有Promise对象解析后的结果。

  •  解析时如果任何一个Promise对象失败,则这个新的Promise实例会立即失败,并返回第一个失败的Promise对象的错误信息。

  • Promise.all不会改变原有的Promise对象的状态,原有的 Promise 对象仍会按照自己的状态(fulfilled或rejected)进行解析。

那么Promise.all的具体实现过程是怎样的?今天来记录学习下,话不多说,直接上代码和注释,

// 手写Promise.all方法
Promise.myPromiseAll = function (props) {
  // 这里定义res、rej变量,在Promsie内部赋值,
  // 这样外部就可以直接调用res()、rej()方法
  let res, rej;
  // 这里定义promise1,用于最后返回最终状态
  const promise1 = new Promise((resolve, reject) => {
    res = resolve;
    rej = reject;
  });

  //定义i 表示Promise对象的数量
  let i = 0;
  // 定义result 用于存储每个成功Promise的结果
  const result = [];
  //定义fulfilled 用于追踪已完成的Promise数量
  let fulfilled = 0;

  // 这里不能使用.length判断props数组长度,因为他有可能是一些别的可迭代对象,
  // 所以这里使用for of循环Promise的参数props,for of可以循环任意的可迭代对象
  for (const item of props) {
    // 这里保存的数据下标index,用于赋值成功后的data数据,形成闭包环境
    const index = i;
    // 这里每循环一次i加1,表示Promise数量
    i++;

    // 这里循环拿到的不一定是一个Promise,所以使用Promise.resolve包装一下,
    // 然后处理成功和失败的状态
    Promise.resolve(item).then((data) => {
      // 这里需要考虑到Promise成功时需要做到什么?1、2、
      // 1、完成的数据汇总到一个数组,最终结果
      // 在上面定义result,于存储每个成功Promise的结果,
      // 这里不能使用push方法,因为我们需要返回的数据是传递的顺序,不是完成的顺序
      // 所以这里根据下标赋值成功后的data数据
      result[index] = data;

      // 2、判定是否全部完成
      // 这里在上面定义fulfilled,记录每次完成fulfilled数量加1
      fulfilled++;
      // 这里判断fulfilled完成的数量和Promise数量相等时表示结束,
      // 把数据result给res
      if (fulfilled === i) { res(result); }

      // 这里如果失败,直接调用失败的方法,因为状态一旦确定就无法更改
    }, rej)
    // 因为这里是异步代码,运行时循环已经结束,所以i代表的一定是整体的数量

  }

  // 这里循环完成,判断i如果等于0,表示没有传递任何Promise参数
  // 直接给一个空数组
  if (i === 0) { res([]); }

  // 最后直接返回最终状态promise1
  return promise1;
}

Promise.myPromiseAll([]).then((res) => {
  console.log(res);
}, (err) => {
  console.log("err", err);
})
// 输出 []

Promise.myPromiseAll([1, 2, 3]).then((res) => {
  console.log(res);
}, (err) => {
  console.log("err", err);
})
// 输出 [1, 2, 3]

Promise.myPromiseAll([1, 2, 3, Promise.reject(456)]).then((res) => {
  console.log(res);
}, (err) => {
  console.log("error", err);
})
// 输出 error 456

Promise.myPromiseAll([1, 2, 3, Promise.resolve(456)]).then((res) => {
  console.log(res);
}, (err) => {
  console.log("err", err);
})
// 输出 [ 1, 2, 3, 456 ]

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

北城笑笑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值