Using async/await with a forEach loop
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.
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 (let 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)
}));
}
To me using Promise.all()
with map()
is a bit difficult to understand and verbose, but if you want to do it in plain JS that's your best shot I guess.
If you don't mind adding a module, I implemented the Array iteration methods so they can be used in a very straightforward way with async/await.
An example with your case:
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);
});
}
printFiles()
p-iteration
以下是一些forEach异步原型:
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));
}
链接地址: http://www.djcxy.com/p/82682.html
上一篇: 在台式机上运行紧凑的框架代码