在前端开发中,异步操作是家常便饭。而 JavaScript 中的 Promise 可以确保异步操作的可靠执行。在 ES11 中新增加了一个非常有用的 Promise 方法:Promise.allSettled。本文将介绍这个方法的使用方法,以及它对异步操作的处理方式有什么不同。
Promise.all 方法存在的问题
在 ES6 中引入的 Promise.all 方法用于并行处理多个异步操作,它接受一个 Promise 数组作为参数,当数组中所有的 Promise 都执行完毕时,才会返回一个 resolve 状态的 Promise,否则返回 reject 状态的 Promise。比如下面的代码片段:
const promises = [Promise.resolve('hello'), Promise.reject('oh no')]; Promise.all(promises).then(values => console.log(values));
在这个例子中,由于数组中的第二个 Promise 返回了一个 reject 状态,Promise.all 就会直接返回一个 reject 状态的 Promise。如果要在考虑到失败的情况下获取所有异步操作的结果,就得像下面这样写:
const promises = [Promise.resolve('hello'), Promise.reject('oh no')]; Promise.all(promises.map(p => p.catch(error => error))) .then(values => console.log(values));
这个方法是可以用的,但是代码看起来就很丑陋。而且更重要的是它只能给开发者返回全部的结果,当其中一个异步操作失败的时候,它就会直接返回 reject 状态的 Promise。
Promise.allSettled 方法的介绍
ES11引入的 Promise.allSettled 方法可以解决上述问题。此方法返回的 Promise 始终是 resolve 状态的,即使其中某些 Promise 返回了一个 reject 状态。返回的是一个数组,数组中每个元素的状态都是一个对象,这个对象包含了相应 Promise 的状态(fulfilled 或 rejected)和返回的值(如果有的话)。例如:
const promises = [Promise.resolve('hello'), Promise.reject('oh no')]; Promise.allSettled(promises).then(values => console.log(values));
这个例子将会打印:
[ { status: 'fulfilled', value: 'hello' }, { status: 'rejected', reason: 'oh no' } ]
Promise.allSettled 方法的用法
如果要用 Promise.allSettled 方法并行处理多个异步操作,可以使用它与 Promise 的链式调用结合的方式来实现。如下面的例子:
-- -------------------- ---- ------- -------------------- -------------------------------------------------------------- -- ------------ --- ----------------- ------- -- ------------- -- ------------------ ------ -- ------------- -- - ---------------------- -- - -- -------------- --- ------------ - ---------------------- -------------- - ---- - --------------------- --------------- - -- --
在这个例子中,我们使用 Promise.allSettled 来处理两个异步操作,一个是利用 fetch 来获取一个远程的 JSON 数据,另一个则是一个用来模拟超时的 Promise。由于 fetch 所返回的 Promise 是一个 resolved 状态的,所以代码会输出 JSON 数据。而另一个 Promise 超过了五秒就会返回一个 rejected 状态的 Promise,所以代码会输出一个超时的错误信息。
结论
Promise.all 在处理多个异步操作时非常有用,但它的处理方式有些许缺陷。在某些情况下,我们需要区分 Promise 所返回的状态,而 Promise.allSettled 很好地解决了这个问题。它不仅可以在所有 Promise 被执行之后给开发者一个 Promise 数组,而且可以告诉开发者执行 Promise 的情况。如果你还没有在自己的项目中使用 Promise.allSettled 方法,那么现在就是时候去尝试一下了。
示例代码
-- -------------------- ---- ------- -------------------- -------------------------------------------------------------- -- ------------ --- ----------------- ------- -- ------------- -- ------------------ ------ -- ------------- -- - ---------------------- -- - -- -------------- --- ------------ - ---------------------- -------------- - ---- - --------------------- --------------- - -- --
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67399401317fbffedf17816f