axios stream.on("data")回调中GET请求无法正常响应问题
问题分析与解决方案
核心问题排查
你的代码中存在两个关键问题:一是stream.on('data')的async回调未捕获错误,导致请求失败时静默无输出;二是HTTP连接池被长连接占用——第一个/subscribe接口返回的stream是长连接,会持续占用Node.js默认HTTP Agent的socket,而默认的maxSockets(单host:port的最大并发连接数)限制会导致后续请求被阻塞,无法获取响应。
分步解决方案
1. 先捕获错误,定位具体问题
在async回调中添加try/catch,明确请求失败的原因:
import axios from 'axios'; const getTasks = async () => { const { data: stream } = await axios.get(`http://127.0.0.1:8000/agent/runners/1/subscribe`, { responseType: 'stream', }); stream.on('data', async (data) => { console.log('received data'); try { const response = await axios.get( `http://127.0.0.1:8000/agent/runners/1/tarball-download-url`, ); console.log('response ', response); } catch (err) { // 打印错误信息,精准定位问题 console.error('请求失败:', err.message, err.code); } }); }; getTasks();
2. 调整HTTP连接池配置,避免长连接阻塞
如果错误显示为连接超时或无法获取socket,可通过自定义HTTP Agent调整连接数或禁用连接复用:
import axios from 'axios'; import http from 'http'; // 创建自定义Agent,增大连接数并禁用长连接复用 const customAgent = new http.Agent({ maxSockets: 20, // 提高单host的最大并发连接数 keepAlive: false, // 禁用连接复用,避免订阅接口长期占用socket }); const getTasks = async () => { const { data: stream } = await axios.get(`http://127.0.0.1:8000/agent/runners/1/subscribe`, { responseType: 'stream', // 也可以给订阅请求单独配置Agent,不占用默认连接池 // httpAgent: new http.Agent({ keepAlive: false }) }); stream.on('data', async (data) => { console.log('received data'); try { const response = await axios.get( `http://127.0.0.1:8000/agent/runners/1/tarball-download-url`, { httpAgent: customAgent } // 使用自定义Agent发起请求 ); console.log('response ', response); } catch (err) { console.error('请求失败:', err); } }); }; getTasks();
3. 节流处理高频data事件
如果data事件触发过于频繁,会导致大量并发请求超出处理能力,可添加节流逻辑:
import axios from 'axios'; import http from 'http'; const customAgent = new http.Agent({ maxSockets: 20 }); let isRequesting = false; // 节流标记,避免同时发起多个请求 const getTasks = async () => { const { data: stream } = await axios.get(`http://127.0.0.1:8000/agent/runners/1/subscribe`, { responseType: 'stream', }); stream.on('data', async (data) => { console.log('received data'); if (isRequesting) return; // 已有请求在处理,跳过当前触发 isRequesting = true; try { const response = await axios.get( `http://127.0.0.1:8000/agent/runners/1/tarball-download-url`, { httpAgent: customAgent } ); console.log('response ', response); } catch (err) { console.error('请求失败:', err); } finally { isRequesting = false; // 请求完成后重置标记 } }); }; getTasks();
内容的提问来源于stack exchange,提问作者Richard
相关产品推荐
相关产品推荐

