基于 ECMA-262 规范模拟实现的 Promise.all 函数

本文详细解释了如何扩展Promise原型,提供.all方法,以同步处理并发请求,确保成功或失败状态的一致性。
摘要由CSDN通过智能技术生成
// 若原生 Promise 不包含 .all 方法,则将其添加
if (typeof Promise.prototype.all !== 'function') {
  Promise.all = function(promises) {
    if (!Array.isArray(promises)) {
      if (promises[Symbol.iterator]) {
        promises = Array.from(promises);
      } else {
        throw new TypeError('Promise.all expects an array or iterable object');
      }
    }

    return new Promise((resolve, reject) => {
      // 用于存放最终结果的数组
      const values = [];
      // 用于记录已完成的 Promise 数量
      let completedCount = 0;
      // 保存输入 Promises 的总数
      const totalPromises = promises.length;

      // 解决单个 Promise 的处理器
      const resolver = (index, value) => {
        values[index] = value;

        // 当所有 Promises 都完成时,解决外部的 Promise
        if (++completedCount === totalPromises) {
          resolve(values);
        }
      };

      // 处理单个 Promise 的拒绝
      const rejecter = (reason) => {
        // 只要有一个 Promise 被拒绝,就拒绝外部的 Promise
        reject(reason);
      };

      // 遍历传入的 Promise 数组
      promises.forEach((p, index) => {
        // 无论传入的 p 是否已经是 Promise,都要使用 Promise.resolve 包装
        Promise.resolve(p).then(
          // 成功回调,将结果存入 values 数组
          value => resolver(index, value),
          // 失败回调,直接拒绝外部的 Promise
          rejecter
        );
      });

      // 特殊处理:如果传入的 promises 数组为空
      if (totalPromises === 0) {
        // 直接解决外部的 Promise,并返回空数组
        resolve([]);
      }
    });
  };
}

// 示例:
const promises = [
  fetch('https://api.example.com/data1'),
  fetch('https://api.example.com/data2'),
];

Promise.all(promises)
  .then(results => {
    console.log('All requests succeeded:');
    results.forEach((response, index) => {
      response.json().then(data => console.log(`Response from ${index + 1}:`, data));
    });
  })
  .catch(reason => console.error('At least one request failed:', reason));

Promise.all 会返回一个新的 Promise,当且仅当所有传入的 Promise 都成功解决时,新的 Promise 才会被解决,解决值是一个数组,包含了每个传入 Promise 解决的值,按照它们在数组中的位置排列。如果有任何一个 Promise 被拒绝,那么新的 Promise 也会立即被拒绝,其拒绝原因就是那个最先被拒绝的 Promise 的拒绝原因。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

开机就来

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

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

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

打赏作者

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

抵扣说明:

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

余额充值