场景:在一个for循环中执行异步请求,请求结果最终需要在循环外部使用。
let targetData = []; let originData = [1,2,3]; for ( let i = 0; i < originData.length; i++ ) { // 这里执行异步ajax 我们用setTimeout模拟 setTimeout(() => { targetData.pusn(i); console.log(targetData); // []
由于异步代码执行是在主栈代码执行结束之后再执行,因此
console.log(targetData)
在执行的时候for循环内部的异步代码并没有执行。因此也就在外部获取不到我们想要的数据。解决方案:
1. 使用Promise.all()进行请求并发处理let targetData = []; let originData = [1,2,3]; let promises = originData.map((item) =>{ return new Promise((resolve, reject) => { // 异步ajax 用setTimeout模拟 setTimeout(() => { targetData.push(item); resolve(); Promise.all(promises).then(() => { console.log(targetData); // [1, 2, 3]
将每次的异步逻辑装在promises数组中。然后调用Promise.all()进行并行请求,然后就能在Promise.all()的then回调里获取到我们想要的值。但是这样会有一个问题,就是当promises数组中其中一个请求挂掉了,那么永远也不能在Promise.all()的then回调里获取到数据。具体处理方法,在我的这篇文章里有叙述Javascript知识零散学习(面试篇)。
2. 使用async / await进行请求逐个处理
let targetData = []; let originData = [1,2,3]; function getAsyncData(i){ return new Promise((resolve,reject) => { setTimeout(() => { targetData.push(i); resolve(); }, 0) async function initalRequest(){ for(let i = 0; i < originData.length; i++){ await getAsyncData(originData[i])