如何在 ES12 中使用 Promise.allSettled() 方法

阅读时长 6 分钟读完

简介

Promise.allSettled() 方法是 ECMAScript 2021 中新增的 Promise 方法,它在 Promise.all() 的基础上进行了扩展。

Promise.all() 方法接收一个 Promise 数组作为参数,返回一个新的 Promise 对象。如果传递的 Promise 数组中所有 Promise 都成功执行(resolve)了,则返回的 Promise 对象状态为 resolve,返回结果是一个包含所有 Promise 解析结果的数组。如果 Promise 数组中有任意一个 Promise 被拒绝(reject),则返回的 Promise 对象状态为 reject,错误信息为 Promise 的错误原因。

但是 Promise.all() 存在一个问题,即当 Promise 数组中存在 Promise 被拒绝时,就会中止所有 Promise 的执行,这样会导致其余 Promise 的解决(resolve)结果丢失。

Promise.allSettled() 方法解决了这个问题,它不会在 Promise 被拒绝时中止其余 Promise 的执行,而是在所有 Promise 解决(resolve/reject)后返回一个包含所有 Promise 的状态和结果的数组。

用法

Promise.allSettled() 方法接收一个 Promise 数组作为参数,返回一个新的 Promise 对象。在所有 Promise 解决(resolve/reject)后,返回一个包含所有 Promise 的状态和结果的数组。

其中,iterable 是一个可迭代对象,如数组或具有 Symbol.iterator 属性的对象。返回的 Promise 对象的状态和结果数组的顺序与传入的可迭代对象的顺序一致。

Promise.allSettled() 方法返回的是一个新的 Promise 对象,因此可以使用链式调用的方式处理该方法返回的 Promise 对象。

示例

下面是一个使用 Promise.allSettled() 方法的简单示例,该示例中的数组中包含两个 Promise 对象,第一个 Promise 对象是成功执行的,第二个 Promise 对象是被拒绝的。

-- -------------------- ---- -------
----- -------- - --- ----------------- ------- -- ------------------- ---- -------- - -------------
----- -------- - --- ----------------- ------- -- ------------------ --- -------- - -------------

----------------------------- ------------------------- -- -
  ---------------------
---

-- ----
-- -
--   - ------- ------------ ------ -------- - ---------- --
--   - ------- ----------- ------- -------- - ---------- -
-- -

通过上面的示例可以看到,即使传入的数组中存在一个被拒绝的 Promise 对象,Promise.allSettled() 方法依然会将所有 Promise 的状态和结果记录在返回值数组中,这可以让我们在项目中更加方便地处理错误信息。

深入理解

了解了 Promise.allSettled() 方法的基本用法之后,我们来深入了解一些内部实现的细节。

返回结果

Promise.allSettled() 方法返回的是一个 Promise 对象,该对象的状态表示传入的所有 Promise 的状态。

如果传入的所有 Promise 都已解决(resolve)了,返回的 Promise 对象状态为 resolved,其值是一个由传入的所有 Promise 对象状态和值组成的数组。如果传入的 Promise 数组中有任意一个 Promise 被拒绝(reject),返回的 Promise 对象则状态为 rejected,其值是一个由传入的所有 Promise 对象的状态和值组成的数组。

Promise 状态

Promise.allSettled() 方法会等待所有 Promise 执行(resolve/reject)完毕后再返回一个 Promise 对象。

如果 Promise 数组中有 Promise 执行被拒绝(reject),Promise.allSettled() 方法并不会直接返回一个 rejected 状态的 Promise 对象,而是会等待所有 Promise 执行完成后,统一返回一个 resolved 状态的 Promise 对象。对于被拒绝的 Promise 对象,其状态会通过 status 字段标识为 rejected,原因以 reason 字段形式存储。

可迭代对象

Promise.allSettled() 方法的参数必须是一个可迭代对象,如数组、Set 等实现了 Symbol.iterator 方法的对象。在遍历可迭代对象时,Promise.allSettled() 方法会将每个元素视为一个 Promise 对象。

执行顺序

Promise.allSettled() 方法返回值数组的顺序与传入的可迭代对象的顺序一致。但是,在同步执行的情况下,Promise.allSettled() 方法会等待所有 Promise 对象执行完毕后才会返回一个 Promise 对象。因此,数组元素的执行顺序并不能保证,也就是说,Promise 之间是并发执行的。

兼容性

目前,Promise.allSettled() 方法仍是 ECMAScript 2021 的新特性,因此在生产环境中需要仔细考虑是否需要使用该方法。考虑到表现稳定性和兼容性,可以针对 Promise.all() 和 Promise.race() 方法做不同的处理,如果 Promise.all() - Promise.race() 方法的效果已经满足需求,那么直接使用即可。

总结

Promise.allSettled() 方法是 ECMAScript 2021 中新增的 Promise 方法,可以让我们更加方便地处理 Promise 数组中的错误信息。当 Promise 执行(resolve/reject)完毕后,Promise.allSettled() 方法会在一个新的数组中返回所有 Promise 对象的状态和值,不会中止其余 Promise 的执行。不过,在实际开发中,我们需要根据实际情况选择使用 Promise.all() 还是 Promise.allSettled() 方法。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/654ddfbf7d4982a6eb73e06e

纠错
反馈