为了账号安全,请及时绑定邮箱和手机立即绑定

使用async / await和forEach循环

/ 猿问

使用async / await和forEach循环

慕田峪7331174 2019-05-22 13:46:01

使用async / await和forEach循环

async/awaitforEach循环中使用是否有任何问题?我正在尝试循环遍历文件数组和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这样的高阶函数,所以我只是想问一下这是否有任何问题。


查看完整描述

5 回答

?
慕沐林林

当然代码确实有效,但我很确定它没有按照你的预期去做。它只是触发多个异步调用,但该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)
  }));}


查看完整回答
反对 回复 2019-05-22
?
汪汪一只猫

使用ES2018,您可以大大简化以上所有答案:

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

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

请参阅规范:https//github.com/tc39/proposal-async-iteration


查看完整回答
反对 回复 2019-05-22
?
蝴蝶不菲

而不是Promise.allArray.prototype.map(不保证Promises的解析顺序)相结合,我使用Array.prototype.reduce,从解决的开始Promise

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

  await files.reduce(async (promise, file) => {
    // This line will wait for the last async function to finish.
    // The first iteration uses an already resolved Promise
    // so, it will immediately continue.
    await promise;
    const contents = await fs.readFile(file, 'utf8');
    console.log(contents);
  }, Promise.resolve());}


查看完整回答
反对 回复 2019-05-22
?
慕斯王

npm上的p-iteration模块实现了Array迭代方法,因此可以使用async / await以非常简单的方式使用它们。

您的案例的一个例子:

const { forEach } = require('p-iteration');const fs = require('fs-promise');(async function printFiles () {
  const files = await getFilePaths();

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


查看完整回答
反对 回复 2019-05-22
?
森栏

这是一些forEachAsync原型。请注意,你需要await他们:

Array.prototype.forEachAsync = async function (fn) {
    for (let t of this) { await fn(t) }}Array.prototype.forEachAsyncParallel = async function (fn) {
    await Promise.all(this.map(fn));}

请注意,虽然您可以在自己的代码中包含它,但不应将其包含在您分发给其他人的库中(以避免污染其全局变量)。


查看完整回答
反对 回复 2019-05-22

添加回答

回复

举报

0/150
提交
取消
意见反馈 邀请有奖 帮助中心 APP下载
官方微信