javafor循环等待_在forEach循环中使⽤异步等待
在forEach循环中使⽤async / await是否有任何问题? 我正在尝试遍历⽂件数组并await每个⽂件的内容。
import fs from 'fs-promise'
async function printFiles () {
const files = await getFilePaths() // Assume this works fine
files.forEach(async (file) => {
const contents = adFile(file, 'utf8')
console.log(contents)
})
}
printFiles()
这段代码确实有效,但是这可能会出问题吗? 我让某⼈告诉我,您不应该在这样的⾼阶函数中使⽤async / await ,所以我只想问⼀下这是否有问题。
#1楼
确保代码确实有效,但是我很确定它不会实现您期望的功能。 它只是触发多个异步调⽤,但是在printFiles之后printFiles函数确实会⽴即返回。
如果forEach顺序读取⽂件, 则实际上不能使⽤forEach 。 只需使⽤现代的for … of循环,在其中await将按预期⼯作:
async function printFiles () {
const files = await getFilePaths();
for (const file of files) {
const contents = adFile(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 = adFile(file, 'utf8')
console.log(contents)
}));
}
#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 = adFile(file, 'utf8');
console.log(contents);
});
})();
#3楼
上⾯的两个解决⽅案都可以⼯作,但是,安东尼奥⽤更少的代码来完成这项⼯作,这就是它如何帮助我从数据库中解析数据,来⾃⼏个不同的⼦引⽤,然后将它们全部推⼊数组并以promise的形式解决,完成:
Promise.all(PacksList.map((pack)=>{
return fireBaseRef.child(pack.folderPath).once('value',(snap)=>{
snap.forEach( childSnap => {
const file = childSnap.val()
file.id = childSnap.key;
allItems.push( file )
})
})
})).then(()=>store.dispatch( actions.allMockupItems(allItems)))
#4楼
在⽂件中弹出⼏个⽅法将很轻松,这些⽅法将以序列化的顺序处理异步数据,并为您的代码提供更传统的风格。 例如:
var self = this;
this.each = async (items, fn) => {
if (items && items.length) {
await Promise.all(
items.map(async (item) => {
await fn(item);
}));
}
};
await self.each(
items, async (item) => {
initialValue = await fn(initialValue, item);
});
return initialValue;
};
};
现在,假设将其保存在“ ./myAsync.js”中,则可以在相邻⽂件中执⾏类似于以下的操作:...
/* your server setup here */
...
var MyAsync = require('./myAsync');
var Cat = require('./models/Cat');
var Doje = require('./models/Doje');
var example = async () => {
var myAsync = new MyAsync();
var doje = await Doje.findOne({ name: 'Doje', noises: [] }).save();
var cleanParams = [];
// FOR EACH EXAMPLE
await myAsync.each(['bork', 'concern', 'heck'],
async (elem) => {
if (elem !== 'heck') {
await doje.update({ $push: { 'noises': elem }});
}
});
var cat = await Cat.findOne({ name: 'Nyan' });
// REDUCE EXAMPLE
var friendsOfNyanCat = duce(cat.friends,
async (catArray, friendId) => {
var friend = await Friend.findById(friendId);
if (friend.name !== 'Long cat') {
await和async使用方法catArray.push(friend.name);
}
}, []);
// Assuming Long Cat was a friend of
assert(friendsOfNyanCat.length === (cat.friends.length - 1));
}
#5楼
⼀个重要的警告是:⽅法的await + for .. of和forEach + async⽅式实际上具有不同的效果。
在真实的for循环中await将确保所有异步调⽤都被⼀个接⼀个地执⾏。 ⽽且forEach + async⽅式将同时触发所有的Promise,这更快但有时会不知所措( 如果您进⾏⼀些数据库查询或访问⼀些具有⾳量限制的Web服务,并且不想⼀次触发100,000个调⽤)。
如果您不使⽤async/await并想确保⽂件被⼀个⼜⼀个地读取,则也可以使⽤reduce + promise (不太优雅)。
lastPromise.then(() =>
), solve()
)
或者,您可以创建⼀个forEachAsync来提供帮助,但基本上可以使⽤相同的for循环基础。
Array.prototype.forEachAsync = async function(cb){
for(let x of this){
await cb(x);
}
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论