Promise 是 JavaScript 中一种常用的处理异步操作的方式,而 Promise.all 方法则是在多个 Promise 并发执行时使用的工具函数。然而,Promise.all 方法会在任意一个 Promise 被 rejected 时,立即终止所有的并发操作,并返回一个 rejected 状态的 Promise 实例。这限制了在并发操作中的容错性。ES7 引入的 Promise.allSettled 方法可以很好地解决这个问题。
什么是 Promise.allSettled 方法
Promise.allSettled 方法是在 ES7 规范中引入的,通过并发执行多个 Promise,并对所有结果进行处理。与 Promise.all 方法不同的是,Promise.allSettled 方法会等待所有 Promise 完成,并且不会在其中任意一个 Promise 被 rejected 时停止执行。返回的结果为一个数组,数组的每一项都包含一个对象,该对象有两个属性:status 和 value(或 reason)。
- status: 表示 Promise 的状态,有两个可能的值:“fulfilled” 或 “rejected”
- value(或 reason): 如果 Promise 状态是 “fulfilled”,则 value 表示 Promise 的 resolve 值,如果是 “rejected”,则 reason 表示 Promise 的 reject 值。
Promise.allSettled 方法的使用
使用 Promise.allSettled 方法可以很方便地处理多个并发操作,并且在所有操作完成后执行后续的操作。下面是一个例子:
const promises = [ Promise.resolve("success"), Promise.reject("failure"), Promise.resolve("success again") ]; Promise.allSettled(promises).then(results => { for (const result of results) { console.log(`${result.status}: ${result.value}`); } });
运行以上代码会输出:
fulfilled: success rejected: failure fulfilled: success again
实现 Promise.allSettled 方法
如果你想了解具体实现方式,可以参考以下的代码:
Promise.allSettled = function(promises) { return new Promise(resolve => { const results = []; let count = promises.length; if (count === 0) { resolve(results); } function handleResult(index, status, value) { results[index] = { status, value }; if (--count === 0) { resolve(results); } } for (let i = 0; i < promises.length; i++) { promises[i].then(value => { handleResult(i, 'fulfilled', value); }, reason => { handleResult(i, 'rejected', reason); }); } }); };
实现方式很简单,通过一个计数器 count 维护并发操作的数量,并在每个 Promise 完成后更新计数器的值。对于每个完成的 Promise,将其结果存入 results 数组。最后,当计数器的值减为 0 时,调用 resolve 并传入 results 数组。对于 Promise 的状态变动,通过 Promise 对象的 then 方法实现。
总结
ES7 引入的 Promise.allSettled 方法为 JavaScript 的 Promise 提供了更好的容错性和可靠性,能在多个 Promise 并发执行时便利地处理并返回所有完成的承诺和执行结果。实现 Promise.allSettled 方法并不难,希望本文能够对你的学习和工作有所启发。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65bb0b90add4f0e0ff3a33ec