静下心来的个人专栏
上一篇

Promise.allSettled()方法

广告
选中文字可对指定文章内容进行评论啦,→和←可快速切换按钮,绿色背景文字可以点击查看评论额。
大纲

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将文件名属性添加到任何拒绝原因,以便在事后更容易解释结果。

当对所有文件的操作完成时,过滤结果以查找转换未成功的任何文件,然后将这些结果输出到控制台。 在生产系统中,您可能会将失败的结果输入监控系统或队列以再次尝试转换。

版权声明:著作权归作者所有。

X

欢迎加群学习交流

联系我们