前言
在 JavaScript 中,Promise 是一种异步编程的解决方案。它可以让我们更加方便地处理异步操作,避免回调地狱的问题,提升代码可读性和可维护性。
在 Promise 中,我们经常会用到 Promise.all() 方法,它可以同时执行多个 Promise 对象,并在所有 Promise 对象执行完成后返回一个新的 Promise 对象。但是,有时候我们需要对每个 Promise 的执行结果进行判断,而不仅仅是等待所有 Promise 都执行完成。这个时候就需要使用 Promise.allsettled() 方法了。
Promise.allsettled() 概述
Promise.allsettled() 方法是在 ES2020 中被引入的,它与 Promise.all() 方法类似,但是不同的是,它会在所有 Promise 对象都执行完成后返回一个新的 Promise 对象,并且该 Promise 对象的状态始终都是 fulfilled,而不会因为其中某个 Promise 失败而变成 rejected。
Promise.allsettled() 方法的语法如下:
Promise.allsettled(iterable)
其中,iterable 是一个可迭代的对象,例如数组或者具有迭代器接口的其他数据结构。
Promise.allsettled() 返回一个新的 Promise 对象,该 Promise 对象会在所有 Promise 对象都执行完成后被 fulfilled。
返回值为一个数组,该数组中的每个元素是一个对象,对象中有两个字段:status 和 value(或 reason),分别表示 Promise 对象的状态(fulfilled 或 rejected)以及 Promise 对象执行的结果(成功时为返回值,失败时为异常信息)。
Promise.allsettled() 方法的实现
在实现 Promise.allsettled() 方法之前,先来回顾一下 Promise.all() 方法的实现。
在 Promise.all() 方法中,我们会通过 Promise.race() 方法来实现同时执行多个 Promise 对象的功能。具体实现代码如下:
// javascriptcn.com 代码示例 Promise.all = function (promises) { return new Promise(function (resolve, reject) { if (!Array.isArray(promises)) { return reject(new TypeError("promises must be an array")); } const len = promises.length; const resolvedValues = new Array(len); let resolvedCount = 0; for (let i = 0; i < len; i++) { Promise.resolve(promises[i]).then( function (value) { resolvedValues[i] = value; resolvedCount++; if (resolvedCount === len) { return resolve(resolvedValues); } }, function (reason) { return reject(reason); } ); } }); };
在上面的代码中,我们首先判断传入的参数是否为数组,然后定义了一个 resolvedValues 数组用于保存每个 Promise 的执行结果,在执行每个 Promise 时,通过 Promise.resolve() 方法将其转换为 Promise 对象,然后利用 Promise.race() 方法实现多个 Promise 并发执行的功能。
在每个 Promise 执行完成后,我们会将其执行结果保存到 resolvedValues 数组中,并更新 resolvedCount 变量,最后根据 resolvedCount 的值决定新的 Promise 对象的状态。
接下来,我们按照类似的思路来实现 Promise.allsettled() 方法。具体实现代码如下:
// javascriptcn.com 代码示例 Promise.allsettled = function (promises) { return new Promise(function (resolve) { const len = promises.length; const resolvedValues = new Array(len); let resolvedCount = 0; for (let i = 0; i < len; i++) { Promise.resolve(promises[i]).then( function (value) { resolvedValues[i] = { status: "fulfilled", value }; }, function (reason) { resolvedValues[i] = { status: "rejected", reason }; } ).finally(function () { resolvedCount++; if (resolvedCount === len) { return resolve(resolvedValues); } }); } }); };
在实现 Promise.allsettled() 方法时,前面的代码逻辑大致相同,不再赘述。我们主要是在每个 Promise 的执行完成的处理函数中,将执行结果保存为一个对象,并存储到 resolvedValues 数组中。
与 Promise.all() 方法不同的是,在每个 Promise 的执行完成处理函数中,我们加入了一个 finally() 方法,该方法会在 Promise 对象执行结束时(不管成功还是失败)都会被执行。通过 resolvedCount 变量和 len 变量的对比,来判断所有 Promise 对象是否都执行完成。
最后返回的 Promise 对象的状态总是 fulfilled,而 resolvedValues 数组中的每个元素,包含了 Promise 对象的状态和返回值(或者失败信息)。
Promise.allsettled() 方法的示例代码
下面是一段简单的示例代码,演示 Promise.allsettled() 方法的使用。
const promise1 = Promise.resolve(3); const promise2 = Promise.reject(new Error("error")); const promise3 = Promise.resolve(7); Promise.allsettled([promise1, promise2, promise3]).then(function (results) { console.log(results); });
输出结果如下:
// javascriptcn.com 代码示例 [ { status: 'fulfilled', value: 3 }, { status: 'rejected', reason: Error: error at file:///path/to/your/file.js:5:19 at new Promise (<anonymous>) at Promise.allsettled (file:///path/to/your/file.js:4:12) at file:///path/to/your/file.js:8:1 }, { status: 'fulfilled', value: 7 } ]
总结
Promise.allsettled() 方法是一个非常实用的 Promise 对象的扩展方法。它可以让我们更容易地对多个 Promise 对象执行结果进行判断,从而更好地处理异步操作。
通过本文,我们了解了 Promise.allsettled() 方法的概念和使用方法,同时还实现了该方法的具体代码。相信读者通过阅读本文后,对于 Promise.allsettled() 的使用已经掌握得比较熟练了,希望本文对您有所启发。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/653647327d4982a6ebe46833