JS中Promise.all 与 Promise.race的区别小结

 更新时间:2026年02月24日 09:49:36   作者:发现一只大呆瓜  
本文主要介绍了JS中Promise.all 与 Promise.race的区别小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

前言

在处理并发请求时,Promise.allPromise.race 是我们的得力助手。理解它们的底层实现,不仅能帮我们应对面试,更能让我们在复杂的异步场景中游刃有余。本文将带你从原理出发,手写这两个核心方法的 TypeScript 版本。

一、 手写 Promise.all

1. 核心作用与逻辑

Promise.all 接收一个 Promise 数组,并返回一个全新的 Promise。

  • 成功条件:只有当所有子 Promise 都变为 fulfilled 时,它才返回所有结果组成的数组。
  • 失败条件:只要有一个子 Promise 变为 rejected,它就立即返回该失败原因。

2. 核心思路

  1. 参数处理:需要将输入参数转为真正的数组,并处理非 Promise 类型的数组成员。
  2. 顺序保证关键! 由于异步执行时间不同,直接 push 结果会导致顺序错乱。必须通过索引 i 来精确存放结果。
  3. 计数器:判断 result.length是否等于数组长度,从而确定所有结果是否已返回。

3. 实现

  function PromiseAll(arr) {
    const promises = Array.from(arr);
    const result = [];
    return new Promise((resolve, rejected) => {
      for (let i = 0; i < promises.length; i++) {
        promises[i]
          .then((res) => {
            result[i] = res;
            if (result.length === promises.length) {
              resolve(result);
            }
          })
          .catch((err) => {
            rejected(err);
          });
      }
    });
  }
  const promise1 = new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(1000);
    }, 1000);
  });
  const promise2 = new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(200);
    }, 200);
  });
  const promise3 = new Promise((resolve, reject) => {
    setTimeout(() => {
      reject(300);
    }, 300);
  });

  PromiseAll([promise1, promise2, promise3])
    .then(function (values) {
      console.log('全部成功', values);
    })
    .catch((values) => {
      console.log('有一个失败', values);
    });

二、 手写 Promise.race

1. 核心作用与逻辑

Promise.race 接收一个 Promise 数组,其状态取决于第一个改变状态(无论成功还是失败)的实例。

2. 核心思路

  1. 抢跑机制:遍历数组中的每一个 Promise,谁先触发回调,就用谁的结果来决议返回的 Promise。
  2. 状态锁定:一旦状态改变,后续的 resolve 或 reject 都会被忽略(Promise 原生机制保证了这一点)。

3. 实现

  function PromiseRace(arr) {
    const promises = Array.from(arr);
    return new Promise((resolve, reject) => {
      try {
        for (let i = 0; i < promises.length; i++) {
          Promise.resolve(promises[i]).then(
            // 第一个成功的结果,直接resolve新Promise
            (value) => resolve(value),
            // 第一个失败的原因,直接reject新Promise
            (reason) => reject(reason)
          );
        }
      } catch (error) {
        // 参数校验/遍历出错时,直接reject新Promise
        reject(error);
      }
    });
  }
  const p1 = new Promise((resolve, reject) => {
    setTimeout(() => {
      reject(100);
    }, 100);
  });
  const p2 = new Promise((resolve) => {
    setTimeout(() => {
      resolve(500);
    }, 5000);
  });
  const p3 = new Promise((resolve) => {
    setTimeout(() => {
      resolve(1000);
    }, 1000);
  });
  PromiseRace([p1, p2, p3])
    .then((res) => console.log(`第一个成功状态:${res}`, 'success'))
    .catch((err) => console.log(`第一个失败状态:${err}`, 'error'));

三、 总结与对比

方法核心关注点核心难点
Promise.all全员完成且顺序一致需使用索引赋值而非 push
Promise.race谁快听谁的 (Winner-takes-all)处理空数组及非 Promise 对象

到此这篇关于JS中Promise.all 与 Promise.race的区别小结的文章就介绍到这了,更多相关JS Promise.all Promise.race内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 基于JavaScript实现随机颜色输入框

    基于JavaScript实现随机颜色输入框

    这篇文章主要介绍了基于JavaScript实现随机颜色输入框的实例代码,代码简单易懂,非常不错,需要的朋友参考下吧
    2016-12-12
  • 移动端h5屏幕适配方案(使用PostCSS插件)

    移动端h5屏幕适配方案(使用PostCSS插件)

    移动端屏幕大小不一,要使网页能自适应不同尺寸的手机屏幕,而且还要尽可能开发便捷,目前使用最多的还是rem大法,这篇文章主要介绍了移动端h5屏幕适配方案的相关资料,需要的朋友可以参考下
    2026-05-05
  • js数组中如何随机取出一个值

    js数组中如何随机取出一个值

    这篇文章主要介绍了js数组中如何随机取出一个值,需要的朋友可以参考下
    2014-06-06
  • JS图片懒加载技术实现过程解析

    JS图片懒加载技术实现过程解析

    这篇文章主要介绍了JS图片懒加载技术实现过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-07-07
  • JavaScript数据结构Map的使用实例详解

    JavaScript数据结构Map的使用实例详解

    JavaScript中Map是ES6引入的数据结构,键可为任意类型,保留插入顺序,支持迭代和size属性,相比对象更灵活高效,适合复杂键和有序场景,但需注意对象键引用比较及NaN的特殊处理,本文给大家介绍JavaScript数据结构Map的使用,感兴趣的朋友一起看看吧
    2025-08-08
  • js 文本框里粘贴一个图片url并显示

    js 文本框里粘贴一个图片url并显示

    不错的应用,一般用于开发系统中,图片新闻,直接显示图片
    2008-08-08
  • JavaScript中的继承之类继承

    JavaScript中的继承之类继承

    在JS中继承是一个非常复杂的话题,比其他任何面向对象语言中的继承都复杂得多。接下来通过本文给大家介绍JavaScript中的继承之类继承,感兴趣的朋友一起看看吧
    2016-05-05
  • JavaScript 未结束的字符串常量常见解决方法

    JavaScript 未结束的字符串常量常见解决方法

    做JavaScript的时候,发现老是出现错误:“未结束的字符串常量”. 自己找了下应该是传参数的时候,有特殊字符引起的.网上也找了下,也有好多出现这种情况.做下总结,以方便以后查阅.
    2010-01-01
  • 使用JS将字符串保存成文件到本地(.txt、.json、.md)

    使用JS将字符串保存成文件到本地(.txt、.json、.md)

    工作中有时需要通过JavaScript保存文件到本地,下面这篇文章主要给大家介绍了关于使用JS将字符串保存成文件到本地的相关资料,分别包括生成.txt、.json、.md等文件,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-06-06
  • javascript实现类似java中getClass()得到对象类名的方法

    javascript实现类似java中getClass()得到对象类名的方法

    这篇文章主要介绍了javascript实现类似java中getClass()得到对象类名的方法,实例分析了javascript实现java中getClass方法的使用技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-07-07

最新评论