Promise.all嵌套axios请求时执行顺序不符预期问题求助
关于Promise.all与axios配合的执行顺序问题
需求:执行多个axios请求,待所有请求完成后再执行后续操作,但目前console.log("THEN PROMISE")早于所有console.log("THEN AXIOS")输出,希望前者在后者全部输出后再执行。
我的代码:
async ajaxPromise() { let me = this; const someFunction = () => { return new Promise(resolve => { setTimeout(() => resolve('222'), 100) }) } async function asyncForEach(array, callback) { for (let index = 0; index < array.length; index++) { debugger; await callback(array[index], index, array); } } let urlObjects = ["https://url1.com", "https://url2.com", "https://url3.com"]; let requestArr = []; await asyncForEach(urlObjects, async (data) => { let waitForThisData = await someFunction(data); requestArr.push( axios.get(data) .then(function (response) { console.log("THEN AXIOS") }) .catch(function (response) { console.log("CATCH AXIOS") }) ); }); Promise.all([ requestArr ]) .then(function (results) { console.log("THEN PROMISE") }) .finally(() => { console.log("FINALLY PROMISE") }) .catch(function (error) { console.log("CATCH PROMISE") }); },
问题出在哪?
Promise.all参数传递错误:你把
requestArr包裹进了另一个数组,写成了Promise.all([requestArr])。这会让Promise.all等待的是一个仅包含数组的"已完成状态"对象(非Promise会被直接判定为resolved),所以它会立刻进入then块,完全不会等待requestArr里的axios请求完成。正确写法是直接传入requestArr:Promise.all(requestArr)。额外优化点:你写的
asyncForEach是串行执行回调,但收集请求Promise不需要串行,直接循环遍历urlObjects把axios请求push到数组即可,这样还能并行发起请求,提升效率。
修正后的代码
async ajaxPromise() { const someFunction = () => { return new Promise(resolve => { setTimeout(() => resolve('222'), 100) }) } let urlObjects = ["https://url1.com", "https://url2.com", "https://url3.com"]; let requestArr = []; // 直接循环收集请求Promise,无需串行的asyncForEach for (const data of urlObjects) { await someFunction(data); requestArr.push( axios.get(data) .then(function (response) { console.log("THEN AXIOS") }) .catch(function (response) { console.log("CATCH AXIOS") }) ); } // 直接传入requestArr给Promise.all Promise.all(requestArr) .then(function (results) { console.log("THEN PROMISE") }) .finally(() => { console.log("FINALLY PROMISE") }) .catch(function (error) { console.log("CATCH PROMISE") }); },
如果不需要等待someFunction串行执行,还可以改成并行发起所有请求,进一步提升效率:
async ajaxPromise() { const someFunction = () => { return new Promise(resolve => { setTimeout(() => resolve('222'), 100) }) } let urlObjects = ["https://url1.com", "https://url2.com", "https://url3.com"]; // 并行处理:先等所有someFunction完成,再批量发起axios请求 await Promise.all(urlObjects.map(data => someFunction(data))); const requestArr = urlObjects.map(data => axios.get(data) .then(() => console.log("THEN AXIOS")) .catch(() => console.log("CATCH AXIOS")) ); Promise.all(requestArr) .then(() => console.log("THEN PROMISE")) .finally(() => console.log("FINALLY PROMISE")) .catch(() => console.log("CATCH PROMISE")); },
内容的提问来源于stack exchange,提问作者Greg
相关产品推荐
相关产品推荐

