P粉6974089212023-08-21 10:27:16
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粉0943518782023-08-21 09:14:18
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.
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); } }
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) })); }