1. ホーム
  2. javascript

[解決済み] forEachループでasync/awaitを使用する

2022-03-18 20:30:55

質問

を使用することに問題はないのでしょうか? 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 をこのような高次の関数で使用した場合、何か問題があるのかどうかをお聞きしたかったのです。

どのように解決するのですか?

確かにこのコードは動作しますが、あなたが期待するような動作をしていないことは確かです。これは複数の非同期呼び出しを行うだけですが、その際に 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 コールバック関数の呼び出しはプロミスを返しますが、あなたはそれを待つのではなく、捨てているのです。ただ 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)
  }));
}