问题描述
在进行业务开发的过程中,使用了数组的高级函数map
,同时使用了ES6语法async/await
,发现在map
循环下任务是异步执行的,并不符合预期
例子说明
/** * 异步打印数据 */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-16i===> 0 23:19:04i===> 1 23:19:04i===> 2 23:19:04i===> 3 23:19:04run-end======>date: 2019-2-16end...//打印结果start...run-start====>date: 2019-2-16run-end======>date: 2019-2-16end...i===> 0 23:19:04i===> 1 23:19:04i===> 2 23:19:04i===> 3 23:19:04
从上面的例子可以看出,在map
循环下使用await
后, 函数结束标志信号run-end
先于异步任务数据i
输出,故task任务仍然是异步执行,并不符合预期。原因是Array的循环方法map、forEach、filter、reduce、some、every等是并行迭代
,可以理解为async/await
的效果是无效的
解决方案
- 使用最原始的for循环
- for...of
将上述的模拟异步任务修改为
for (var i = 0; i < dataArr.length; i++) { await echo(i) } 或 for (const i of dataArr) { await echo(i) }