阵列在foreach是异步比较正常的循环
问题描述:
我刚开始探索ES6 async/await
,我发现一些真正的惊喜me.Basically,forEach
表现异步而for
循环表现同步这里例如阵列在foreach是异步比较正常的循环
function getData(d) {
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve(d.x+" %%%% ")
},1000)
})
}
const data=[{x:"aaa"},{x:"bbb"}]
//async for loop
const makeRequest1 = async() => {
for (let i in data){
let value=data[i]
console.log(value)
value.p=await getData(value)
console.log(JSON.stringify(value)+ ' after')
}
// console.log(rr)
console.log(data)
console.log("Is it block ??")
return "done"
}
// { x: 'aaa' }
// {"x":"aaa","p":"aaa %%%% "} after
// { x: 'bbb' }
// {"x":"bbb","p":"bbb %%%% "} after
// [ { x: 'aaa', p: 'aaa %%%% ' }, { x: 'bbb', p: 'bbb %%%% ' } ]
// Is it block ??
// done
//async for loop
const makeRequest2 = async() => {
data.forEach(async (value)=>{
console.log(value)
value.p=await getData(value)
console.log(JSON.stringify(value)+ ' after')
})
console.log(data)
console.log("Is it block ??")
return "done"
}
// { x: 'aaa' }
// { x: 'bbb' }
// [ { x: 'aaa' }, { x: 'bbb' } ]
// Is it block ??
// done
// {"x":"aaa","p":"aaa %%%% "} after
// {"x":"bbb","p":"bbb %%%% "} after
makeRequest2().then((r)=>{
console.log(r)
})
我知道for
和forEach
版本应该同步运行,在这种情况下forEach
怎么会变成异步?
答
想想Promsies方面(这是异步/等待真的是)
诠释,他的第一个情况下,你要链接的承诺,就像你会做
getData(data[0])
.then((val) => console.log(...))
.then(() => getData(data[1])
.then(...
在第二种情况下,你“再打电话只是所有承诺一次,因为forEach
运行瞬间并注册那些许诺,你会:
data.forEach(x => getData(x).then(val => console.log(...)));
注意,在这种情况下的getData(1)d实际上并不等待getData(0)完成 - 没有链接。您在forEach内部的等待只是在每个承诺中链接一个,然后只捕获仍在forEach内的下一段代码
这意味着这些承诺将在第二种情况下相互之间异步运行。
如果你确实想这一点,但要等待所有的调用来完成(使用第二种方法),你只需要一个Promise.all +地图的方法:
const res = await Promise.all(data.map(item => getData(item)));
这将有效将结果数组中的每个项目中的每个项目的getData结果都带上,但请记住这些调用都是异步的。
此外,没有办法使用标准forEach
来使该函数等待彼此。你可以使用一个reduce
操作,而不是这样:
await data.reduce((intermPromise, item) => intermPromise.then(getData(item)), Promise.resolve());
这基本上通过减少阵列,从一个单元无极链的每个项目的呼吁。外面最后的等待将用于与所有呼叫链接的最终承诺。
还要注意使用map
方法之间的差异 - 和reduce
方法 - - 在这里你实际上得到一个数组轻松所有结果(但它运行异步),你在哪里得到同步调用,但最终的结果将不会返回一个数组,实际上它只会返回最后一次调用的结果。
希望这会有所帮助。
也许是因为在回调前的'async' ... – Weedoze
@Weedoze很有可能,是否有任何详细的解释 – Guigui
您是说您正在探索'async'和'await',然后阅读文档。这会给你解释 – Weedoze