Promise.allSettled()方法

Promise.allSettled() 方法是 Promise.all() 的一个轻微变体,其中该方法等待直到指定迭代中的所有 Promise 都settled,无论它们是fulfilled还是rejected。Promise.allSettled() 的返回值始终是一个由结果对象数组实现的Promise。
fulfilled promise的结果对象有两个属性:
status - 始终设置为fulfilled
value - promise的fulfillment值
对于rejected的promise,结果对象还有两个属性:
status - 始终设置为rejected
reason - promise的rejected值
您可以使用返回的结果对象数组来确定每个单独promise的结果。
let promise1 = Promise.resolve(42);
let promise2 = Promise.reject(43);
let promise3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(44);
}, 100);
});
let promise4 = Promise.allSettled([promise1, promise2, promise3]);
promise4.then(results => {
console.log(Array.isArray(results)); // true
console.log(results[0].status); // "fulfilled"
console.log(results[0].value); // 42
console.log(results[1].status); // "rejected"
console.log(results[1].reason); // 43
console.log(results[2].status); // "fulfilled"
console.log(results[2].value); // 44
});
即使第二个promise (promise2) 是一个rejected的promise,对 Promise.allSettled() 的调用也会返回一个带有结果对象数组的fulfillment promise。 然后,您可以查看结果对象以确定每个promise的结果。
何时使用 Promise.allSettled()
Promise.allSettled()方法可以在许多与 Promise.all() 相同的情况下使用; 但是,它最适合您想要忽略rejection、以不同方式处理rejection或允许部分成功的情况。 以下是 Promise.allSettled() 的一些常见用例。
分别处理多个文件
在讨论 Promise.all() 时,您看到了一个处理多个相互依赖才能成功的文件的示例。 在某些情况下,单独处理多个文件意味着如果一个文件失败,您不需要停止整个操作;而是您继续完成成功的操作,然后记录失败的操作以稍后重试。 这是 Node.js 中的一个示例:
import { readFile, writeFile } from "node:fs/promises";
// or any operation on the files
function transformText(text) {
return text.split("").reverse().join("");
}
function transformFiles(filenames) {
return Promise.allSettled(
filenames.map(filename =>
readFile(filename, "utf8")
.then(text => transformText(text))
.then(newText => writeFile(filename, newText))
.catch(reason => {
reason.filename = filename;
return Promise.reject(reason);
})
)
);
}
transformFiles([
"file1.txt",
"file2.txt"
]).then(results => {
// get failed results
const failedResults = results.filter(
result => result.status === "rejected"
);
if (failedResults.length) {
console.error("The following files were not transformed successfully:");
console.error("");
failedResults.forEach(failedResult => {
console.error(failedResult.reason.filename);
console.error(failedResult.reason.message);
console.error("");
});
} else {
console.log("All files transformed successfully.");
}
});
此示例读入一系列文件,反转文件中文本的顺序,然后将该文本写回原始文件(当然,您可以将transformText 替换为您喜欢的任何操作)。 transformFiles() 函数接受文件名数组并读取文件的内容,转换文本,然后将转换后的文本写回文件。 Promise链代表流程中的每个步骤,rejection handler将文件名属性添加到任何拒绝原因,以便在事后更容易解释结果。
当对所有文件的操作完成时,过滤结果以查找转换未成功的任何文件,然后将这些结果输出到控制台。 在生产系统中,您可能会将失败的结果输入监控系统或队列以再次尝试转换。