Use async/await and forEach loops to operate
P粉010967136
P粉010967136 2023-08-20 11:27:20
0
2
537
<p>Are there any problems with using <code>async</code>/<code>await</code> inside a <code>forEach</code> loop? I'm trying to loop through an array of files and use <code>await</code> on the contents of each file. </p> <pre class="brush:php;toolbar:false;">import fs from 'fs-promise' async function printFiles () { const files = await getFilePaths() // Assume this function works properly files.forEach(async (file) => { const contents = await fs.readFile(file, 'utf8') console.log(contents) }) } printFiles()</pre> <p>This code does work, but are there any problems with doing so? I was told that I shouldn't use <code>async</code>/<code>await</code> in higher order functions like this, so I wanted to ask if there are any questions. </p>
P粉010967136
P粉010967136

reply all(2)
P粉697408921

Using ES2018 you can greatly simplify all the answers above:

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

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

View specification:proposal-async-iteration

Simplified:

for await (const results of array) {
    await longRunningTask()
  }
  console.log('I will wait')

2018-09-10: This answer has been getting a lot of attention lately, see Axel Rauschmayer's blog post for more information on asynchronous iteration.

P粉094351878

Of course, the code does work, but I'm pretty sure it won't work as you expect. It just triggers multiple async calls, but the printFiles function returns immediately after that.

Read in order

If you want to read the file sequentially, indeed you cannot use forEach. Instead, you can use a modern for … of loop, where await will work as expected:

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

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

Parallel reading

If you want to read files in parallel, indeed you cannot use forEach. Each async callback function call returns a promise, but you throw them away instead of waiting for them. Instead, you can use map and wait for the resulting array of promises using 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)
  }));
}
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template