在foreach中实现异步
首先。 在foreach中打印出1,2,3,4,5
需要在执行for的时候,指定元素的作用域
a.forEach(i=>{
console.log(i)
})
for(var i=0; i< a.length; i++){
((m)=>setTimeout(()=>console.log(m), 1000))(a[i]);
}
for(var i in a){} // 0, 1,2
for(var i of a){} // 1,2,3
然后, 由于foreach中现存的bug
无法执行异步等待, 也就是如果我foreach中执行等待, 不是我们期待的每个1s打印出来数据, 然后等待1s后, 数据全打印出来了。
具体表现为:
今天我在工作中遇到一个问题, 使用sequelize, 迭代求得一个领导下面所有的员工, A->(B/ C/ D) -> (B->E/F) / (C->G/H)/ (D->J/K)都要返回A-H.可是子树也是异步。我遇到的问题是, 子树的递归结果没有返回, 返回的是A/B/C/D/Promise<>/Promise<>/Promise<>.
我的代码是这样写的,看起来没有错, 但是子元素并没有执行完。 结果就返回了。 原因是foreach并没有await的支持。
async function findAllEmployee(soeid){
let data = []
const result =await Develope.find({where: {DirectManagerSOEID: soeid}})
result.forEach(async i=> {
const tmp = await Develope.find({where: {DirectManagerSOEID: i}})
data = data.concat(tmp);
});
data = data.concat(result);
return data;
}
需要将代码改成
async function findAllEmployee(soeid){
let data = []
const result =await Develope.find({where: {DirectManagerSOEID: soeid}})
for(i of result){
const tmp = await Develope.find({where: {DirectManagerSOEID: i}})
data = data.concat(tmp);
}
data = data.concat(result);
return data;
}
扩展一下:for of的原理
//可以iterator的数据是有这样的数据结构
var m = {
[Symbol.iterator]: function(){
return this;
},
next: function(){
return {done: false, value: '123'};
}
}
// for of相当于, 也会自执行异步
for(let VALUE of ITERATORS){
VALUE
statemen
}
var iterator$ = mSymbol.iterator;
var element$ = iterator$.next();
while(element$.done===false){
VALUE = element$.value;
statement
element$ = element$.next()
}
扩展2: foreach await的扩展
async function asyncForeach(array, callback){
for(let i=0;i<array.length;i++){
await callback(array[i]);
}
}
async function test(){
asyncForeach(a, async (i)=>{
await wait1s();
console.log(i+'--------------'+new Date);
});
}
async function test1(){
for(let m of a){
await wait1s();
console.log(m+'--------------'+new Date);
}
}
test1();