Axios嵌套.then与map异步请求后返回空数组问题求助
问题原因分析
你遇到的空数组问题,核心是异步请求还没完成就提前返回了数组。第三个.then里,循环发起的Axios请求是异步操作,代码不会等待这些请求全部执行完毕,就直接return theArrayToFill,此时数组自然是空的。另外还有个明显问题:你的config2里的URL没有用到循环的id,等于所有请求都发往同一个地址,这显然不符合需求。
修复方案
方案1:用Promise.all配合链式.then
把每个Axios请求包装成Promise并收集到数组中,用Promise.all等待所有请求完成后再返回结果:
var axios = require('axios'); var config = { method: 'get', url: '.../api/firstCall', headers: { 'Authorization': 'XXXXXXX', 'Cookie': 'XXXXXXXX' } }; axios(config) .then(function (response) { return response.data.requests; }) .then(function (requests) { // 简化提取ids的写法 return Object.values(requests).map(element => element.id); }) .then(function (ids) { // 生成所有请求的Promise数组 const requestPromises = ids.map(id => { var config2 = { method: 'get', // 务必把id拼接到URL中 url: `.../api/secondCall/${id}`, headers: { 'Authorization': 'XXXX', 'Cookie': 'XXXX' } }; // 返回单个请求的Promise,失败时返回null避免整体失败 return axios(config2) .then(response => response.data) .catch(error => { console.log(`请求id ${id}失败:`, error); return null; }); }); // 等待所有请求完成后返回结果数组 return Promise.all(requestPromises); }) .then(function (theArray) { // 过滤掉请求失败返回的null const validData = theArray.filter(item => item !== null); res.send(validData); }) .catch(function (error) { console.log(error); });
方案2:用async/await简化代码(更易读)
用async/await替代链式.then,逻辑更清晰直观:
var axios = require('axios'); async function fetchData() { try { // 第一个请求 const config = { method: 'get', url: '.../api/firstCall', headers: { 'Authorization': 'XXXXXXX', 'Cookie': 'XXXXXXXX' } }; const firstResponse = await axios(config); const requests = firstResponse.data.requests; // 提取ids const ids = Object.values(requests).map(element => element.id); // 批量发起第二个请求 const requestPromises = ids.map(id => { const config2 = { method: 'get', url: `.../api/secondCall/${id}`, headers: { 'Authorization': 'XXXX', 'Cookie': 'XXXX' } }; return axios(config2) .then(res => res.data) .catch(err => { console.log(`请求id ${id}失败:`, err); return null; }); }); const theArray = await Promise.all(requestPromises); const validData = theArray.filter(item => item !== null); res.send(validData); } catch (error) { console.log(error); } } // 执行函数 fetchData();
关键注意点
Promise.all会等待所有传入的Promise完成后,才返回结果数组,确保所有请求结束后再返回数据。- 必须把循环的
id拼接到第二个请求的URL中,否则所有请求都会指向同一个地址。 - 单个请求失败时返回
null,可以避免一个请求失败导致整个Promise.all失败(如果要求所有请求必须成功,可去掉这个处理)。
内容的提问来源于stack exchange,提问作者Arthur Fortin
相关产品推荐
相关产品推荐

