Using async/await with a forEach loopAsk Questions

 Posted on 09/24/2019

Are there any issues with using async/await in a forEach loop? I'm trying to loop through an array of files and await on the contents of each file.

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()

This code does work, but could something go wrong with this? I had someone tell me that you're not supposed to use async/await in a higher order function like this, so I just wanted to ask if there was any issue with this.

Share On: facebook gplus twitter
profile
Asked by Navin Gondoliya on 09/24/2019 Score: 24 points
Add Comment:

Comments

2 Answers

0 Corrected Answers
Aproved Answers
0
Profile
Answered by hardik chaudhary on 9/28/2019 3:31:26 PM Score: 557 points

With ES2018, you are able to greatly simplify all of the above answers to:

async function printFiles ()

{ const files = await getFilePaths()

for await (const file of fs.readFile(file, 'utf8'))

{ console.log(contents) }

}

See spec: proposal-async-iteration

Comments

Add Comment:
Aproved Answers
1
Profile
Answered by Steve Summit on 9/24/2019 8:06:36 AM Score: 52 points

Sure the code does work, but I'm pretty sure it doesn't do what you expect it to do. It just fires off multiple asynchronous calls, but the printFiles function does immediately return after that.

If you want to read the files in sequence, you cannot use forEach indeed. Just use a modern for … of loop instead, in which 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);

}

}

If you want to read the files in parallel, you cannot use forEach indeed. Each of the async callback function calls does return a promise, but you're throwing them away instead of awaiting them. Just use map instead, and you can await the array of promises that you'll get with 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)

}));

}

Comments

Add Comment:

Post Your Answers

Existing Members

Sign in to your account
Email Address
Password
New Member?
Sign up and complete profile
Full Name
Email Address
I have read and agree to the Terms of Service and Privacy Policy
Please subscribe me to the StoodQ newsletters
Guideline to answer a question:

Useful tips to submit your answer
Please read below guidelines before you submit your answer for question.

  • Read and understand question for which you are submitting your answer.
  • Try to avoid grammatical and spell mistake while answering.
  • Do not post any irrelevant information in your answer.
  • Explain your answer with example or any reference link to help who posted question.
  • If you find irrelevant question, please report it to support. Click here to contact support.
  • You agree to the privacy policy and terms of use to submit any contents.

Note: StoodQ is online developers community which helps developer for their difficulty, lets help them with your value contribution.