将 async/await 与 forEach 循环一起使用

新手上路,请多包涵

async 循环中使用 await / forEach 有什么问题吗?我正在尝试遍历一组文件并 await 每个文件的内容。

import fs from 'fs-promise'

async function printFiles () {
  const files = await getFilePaths() // Assume this works fine

  files.forEach(async (file) => {
    const contents = await fs.readFile(file, 'utf8')
    console.log(contents)
  })
}

printFiles()

这段代码确实有效,但会不会出现问题?有人告诉我,你不应该在这样的高阶函数中使用 async / await ,所以我只是想问一下这是否有任何问题。

原文由 Saad 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 949
1 个回答

当然代码确实可以工作,但我很确定它没有按照您的预期做。它只是触发多个异步调用,但 printFiles 函数会在此之后立即返回。

按顺序阅读

如果要按顺序读取文件,则确实 不能使用 forEach 。只需使用现代 for … of 循环,其中 await 将按预期工作:

 async function printFiles () {
 const files = await getFilePaths();

 for (const file of files) {
 const contents = await fs.readFile(file, 'utf8');
 console.log(contents);
 }
 }

并行阅读

如果您想并行读取文件,则确实 不能使用 forEach 。每个 async 回调函数调用都会返回一个 Promise,但您将它们扔掉而不是等待它们。只需使用 map 代替,您就可以等待通过 Promise.all 获得的一系列承诺:

 async function printFiles () {
 const files = await getFilePaths();

 await Promise.all(files.map(async (file) => {
 const contents = await fs.readFile(file, 'utf8')
 console.log(contents)
 }));
 }

原文由 Bergi 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题