Node.js使用Axios批量请求无响应问题求助
解决Node.js Axios批量请求无响应的问题
你遇到的核心问题是一次性发起200个并发请求,这很容易触发服务器的限流机制,或者把Node.js的HTTP连接池占满,导致请求挂起毫无响应。另外你代码里用for (var url in urls)直接调用请求函数却没加await,导致所有请求同时扎堆发出,而且代码根本没等待请求完成,自然看不到回调结果。
下面给你几个可行的解决方案:
1. 串行请求(逐个处理)
如果服务器对并发限制严格,或者你不需要极致效率,用for...of循环逐个发起请求是最稳妥的方式,每个请求完成后再处理下一个:
// 先给sendRequest加错误处理和日志追踪 async function sendRequest(url) { try { console.log(`正在请求: ${url}`); const resp = await axios.get(url, { timeout: 10000 }); // 设置10秒超时,避免无限等待 return { url, data: resp.data }; } catch (err) { console.error(`请求${url}失败:`, err.message); return { url, error: err.message }; } } // 批量串行请求函数 async function fetchAllSerial(urlsArray) { const allResults = []; for (const url of urlsArray) { const result = await sendRequest(url); allResults.push(result); } return allResults; } // 调用时注意:如果urls是对象(你用了for in),先转成数组 const urlsArray = Object.values(urls); fetchAllSerial(urlsArray) .then(results => { console.log("所有请求完成!"); // 在这里处理results做后续分析 console.log("成功请求数:", results.filter(r => !r.error).length); console.log("失败请求数:", results.filter(r => r.error).length); }) .catch(err => console.error("全局错误:", err));
2. 并发控制(分批处理)
想兼顾效率和避免限流的话,可以把请求分成批次,比如每次并发10个,完成一批再处理下一批:
async function fetchInBatches(urlsArray, batchSize = 10) { const allResults = []; for (let i = 0; i < urlsArray.length; i += batchSize) { const batchUrls = urlsArray.slice(i, i + batchSize); console.log(`正在处理第${Math.floor(i/batchSize)+1}批次,共${batchUrls.length}个请求`); // 并行处理当前批次的所有请求 const batchResults = await Promise.all( batchUrls.map(url => sendRequest(url)) ); allResults.push(...batchResults); } return allResults; } // 调用 const urlsArray = Object.values(urls); fetchInBatches(urlsArray, 10) // 可根据服务器情况调整batchSize .then(results => { console.log("所有批次处理完成!"); // 后续分析逻辑 }) .catch(err => console.error("全局错误:", err));
3. 优化Axios的连接配置
还可以通过配置Axios的HTTP Agent来控制并发连接数,避免占满连接池:
const axios = require('axios'); const http = require('http'); const https = require('https'); // 创建自定义Agent,限制最大并发连接数,开启keep-alive复用连接 const httpAgent = new http.Agent({ keepAlive: true, maxSockets: 10 }); const httpsAgent = new https.Agent({ keepAlive: true, maxSockets: 10 }); async function sendRequest(url) { try { const resp = await axios.get(url, { timeout: 10000, httpAgent, httpsAgent }); return { url, data: resp.data }; } catch (err) { return { url, error: err.message }; } }
额外检查点
- 先手动测试几个URL,确认这些API本身能正常访问,没有拼写错误或服务器不可达的情况。
- 检查服务器是否返回限流响应(比如429状态码),如果有,可能需要在请求失败后加重试机制,或者延长批次间隔。
- 可以在
sendRequest里打印请求的状态码,确认请求是否真的发到了服务器。
内容的提问来源于stack exchange,提问作者Jaka Krajnc
相关产品推荐
相关产品推荐

