最近寫koa的時候遇見需要在循環中使用async/await的情況,當然第一反應就是直接上forEach
,然後就直接翻車了。。。
直接上代碼:
function handleSql(val) {
return new Promise((resolve) => {
setTimeout(() => {
console.log(`延時${val}秒觸發`)
resolve(val);
}, 1000);
})
}
[1,2,3].forEach(async index => {
console.log('調用await之前',index)
const result = await handleSql(index);
console.log('調用await之後',index)
})
在我的預期中應該是這樣輸出的:
結果他是這樣輸出的:
先循環3次執行 console.log('調用await之前',index)
語句,然後等待一秒後執行了console.log(`延時${val}秒觸發`)
和console.log('調用await之後',index)
語句。
查了一下MDN的forEach文檔發現有這麼一句話:
注意: 沒有辦法中止或者跳出 forEach 循環,除了拋出一個異常。如果你需要這樣,使用forEach()方法是錯誤的,你可以用一個簡單的循環作爲替代。
原來是forEach中不支持這種騷操作,果斷換成普通的for循環或者for ... of:
async function forFn() {
for(let index of [1,2,3]){
console.log('調用await之前',index)
const result = await handleSql(index);
console.log('調用await之後',index)
}
}
async function forFn() {
for(var index = 1;index<4;index++) {
console.log('調用await之前',index)
const result = await handleSql(index);
console.log('調用await之後',index)
}
}
執行後的效果就是我們的預期效果: