在進行業務開發的過程當中,使用了數組的高級函數map
,同時使用了ES6語法async/await
,發如今map
循環下任務是異步執行的,並不符合預期html
/** * 異步打印數據 */ const echo = async (i) => { return new Promise((resolve,reject)=>{ setTimeout(() => { console.log('i===>', i,new Date().toLocaleTimeString()); resolve(i) ; }, 100); }) } /** * 模擬異步任務 */ const task = async () => { dataArr.forEach( async( item, i ) => { await echo(i); }) } /** * 啓動函數入口 */ const run = async () => { console.log('run-start====>date:', new Date().toLocaleDateString()) await task() ; console.log('run-end======>date:', new Date().toLocaleDateString()) } /** * 啓動函數 */ (async () => { console.log('start...') await run(); console.log('end...') })() //預期效果 start... run-start====>date: 2019-2-16 i===> 0 23:19:04 i===> 1 23:19:04 i===> 2 23:19:04 i===> 3 23:19:04 run-end======>date: 2019-2-16 end... //打印結果 start... run-start====>date: 2019-2-16 run-end======>date: 2019-2-16 end... i===> 0 23:19:04 i===> 1 23:19:04 i===> 2 23:19:04 i===> 3 23:19:04
從上面的例子能夠看出,在map
循環下使用await
後, 函數結束標誌信號run-end
先於異步任務數據i
輸出,故task任務仍然是異步執行,並不符合預期。緣由是Array的循環方法map、forEach、filter、reduce、some、every等是並行迭代
,能夠理解爲async/await
的效果是無效的數組
將上述的模擬異步任務修改成異步
for (var i = 0; i < dataArr.length; i++) { await echo(i) } 或 for (const i of dataArr) { await echo(i) }
用 async/await 來處理異步
await在forEach不起做用解決
JavaScript 異步循環 - async/await 的使用方法