使用async / await和forEach循环async/await在forEach循环中使用是否有任何问题?我正在尝试循环遍历文件数组和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这样的高阶函数,所以我只是想问一下这是否有任何问题。
5 回答
慕沐林林
TA贡献2016条经验 获得超9个赞
当然代码确实有效,但我很确定它没有按照你的预期去做。它只是触发多个异步调用,但该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
回调函数调用都会返回一个promise,但是你将它们丢弃而不是等待它们。只需使用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) }));}
蝴蝶不菲
TA贡献1810条经验 获得超4个赞
而不是Promise.all
与Array.prototype.map
(不保证Promise
s的解析顺序)相结合,我使用Array.prototype.reduce
,从解决的开始Promise
:
async function printFiles () { const files = await getFilePaths(); await files.reduce(async (promise, file) => { // This line will wait for the last async function to finish. // The first iteration uses an already resolved Promise // so, it will immediately continue. await promise; const contents = await fs.readFile(file, 'utf8'); console.log(contents); }, Promise.resolve());}
慕斯王
TA贡献1864条经验 获得超2个赞
npm上的p-iteration模块实现了Array迭代方法,因此可以使用async / await以非常简单的方式使用它们。
您的案例的一个例子:
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); });})();
森栏
TA贡献1810条经验 获得超5个赞
这是一些forEachAsync
原型。请注意,你需要await
他们:
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));}
请注意,虽然您可以在自己的代码中包含它,但不应将其包含在您分发给其他人的库中(以避免污染其全局变量)。
添加回答
举报
0/150
提交
取消