ES6 Promise.all 用法详解与异常处理陷阱

作者:异步漫步

时间:2026-10-25

浏览:577

本文详细解析 ES6 中 Promise.all 的使用方法及核心细节。Promise.all 用于并行执行多个异步操作,并在所有操作完成后执行回调。其结果数组的顺序与输入顺序一致。重点讨论了当某个 Promise 被 reject 时,Promise.all 的状态变化,特别是当子 Promise 拥有自定义 catch 方法时,不会触发 Promise.all 的失败回调这一关键陷阱。

文章目录

Promise.all 基本用法

ES6 Promise.all 用法

Promise.all 方法允许并行执行多个异步操作,并在所有异步操作执行完毕后,再执行最终的回调函数。该方法可以将多个 Promise 实例包装成一个新的 Promise 实例。

const p = Promise.all([p1, p2, p3]);

在上述代码中,Promise.all 方法接收一个数组作为参数,其中 p1、p2、p3 均为 Promise 实例。如果传入的参数不是 Promise 实例,Promise.all 会先调用 Promise.resolve 方法将其转换为 Promise 实例,然后再进行后续处理。需要注意的是,Promise.all 的参数不一定必须是数组,但必须具有 Iterator 接口,且返回的每个成员都必须是 Promise 实例。

Promise.all 状态判定机制

新创建的 Promise 实例 p 的状态取决于 p1、p2、p3 的状态,具体分为两种情况。

  1. 只有当 p1、p2、p3 的状态全部变为 fulfilled 时,p 的状态才会变为 fulfilled。此时,p1、p2、p3 的返回值会组成一个数组,传递给 p 的回调函数。
  2. 只要 p1、p2、p3 中有一个实例被 rejected,p 的状态就会变为 rejected。此时,第一个被 reject 的实例的返回值,会传递给 p 的回调函数。

Promise.all 异常处理陷阱

然而,这里有一个需要特别注意的细节。

如果作为参数的 Promise

实例自身定义了 catch 方法,那么即使它被 rejected,也不会触发 Promise.all() 的 catch 方法。

const p1 = new Promise((resolve, reject) => {
  resolve('hello');
})
.then(result => result)
.catch(e => e);

const p2 = new Promise((resolve, reject) => {
  throw new Error('报错了');
})
.then(result => result)
.catch(e => e);

Promise.all([p1, p2])
.then(result => console.log(result))
.catch(e => console.log(e));
// ["hello", Error: 报错了]

在上述代码中,p1 会 resolved,p2 首先会 rejected。但是,由于 p2 拥有自己的 catch 方法,该方法返回的是一个新的 Promise 实例,p2 实际上指向了这个新实例。该新实例执行完 catch 方法后,也会变为 resolved,导致 Promise.all() 参数中的两个实例都变为 resolved。因此,会调用 then 方法指定的回调函数,而不会调用 catch 方法指定的回调函数。

如果 p2 没有自己的 catch 方法,则会调用 Promise.all() 的 catch 方法。

then 方法会将所有异步操作的结果放入一个数组中,并传递给 then 回调,即下面的 results。

Promise
.all([runAsync1(), runAsync2(), runAsync3()])
.then(function(results){
    console.log(results);
});

Promise.all 异步应用示例

附:Promise.all 的异步用法

    const promise1 = Promise.resolve(3);
    const promise2 = 42;
    const promise3 = new Promise((resolve, reject) => {
      setTimeout(resolve, 100, 'foo');
    });
 
    Promise.all([promise1, promise2, promise3]).then((values) => {
      console.log(values);
    });
    // expected output: Array [3, 42, "foo"]

总结

到此这篇关于 ES6 Promise.all 的使用方法以及其细节的文章就介绍到这了,更多相关 ES6 Promise.all 使用内容请搜索本站以前的文章或继续浏览下面的相关文章,希望大家以后多多支持本站!

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章