问题描述
在进行业务开发的过程中,使用了数组的高级函数 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 后,task任务仍然是异步任务,并不符合预期。原因是Array的map、forEach等函数 不会等到所有的步骤都完成,它只会执行任务和执行下一步,可以理解为 async/await 的效果是无效的
解决方案
- 使用最原始的for循环
- for...of
将上述的模拟异步任务修改为
for (var i = 0; i < dataArr.length; i++) { await echo(i) } 或 for (const i of dataArr) { await echo(i) }