Axios 在 Node.js 中处理流式响应(responseType: 'stream')时,若在 stream.on('data') 回调中发起新的 Axios 请求却始终不返回,通常并非前端代码问题,而是后端服务器并发处理能力受限所致。
axios 在 node.js 中处理流式响应(`responsetype: 'stream'`)时,若在 `stream.on('data')` 回调中发起新的 axios 请求却始终不返回,通常并非前端代码问题,而是后端服务器并发处理能力受限所致。
在使用 Axios 订阅服务端 SSE 或 HTTP 流(如 /subscribe 接口)时,常见误区是将流式请求与后续同步/异步逻辑混为一谈。你提供的代码逻辑本身语法正确、无 Promise 拦截或未处理异常:
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 (chunk) => { 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.data); // ❌ 从未执行 } catch (err) { console.error('Nested request failed:', err.message); } });};getTasks();
表面上看,await axios.get(...) 在 data 事件回调中应能正常执行;但实际运行中该 Promise 永远 pending,根本原因在于:后端服务器无法并行处理多个请求。
以 Laravel 默认的 PHP 内置开发服务器(php artisan serve)为例,它本质是单进程、阻塞式、一次仅服务一个请求的 HTTP 服务器。当 /subscribe 接口返回长连接流(HTTP chunked encoding,连接保持打开),该连接会持续占用一个 PHP 进程 —— 导致后续对 /tarball-download-url 的请求被排队甚至阻塞,直到前一个流连接关闭(而流设计本就是“永不关闭”的)。因此,即使前端发出了请求,后端根本未开始处理,自然不会返回响应,Axios 的 Promise 也就永远无法 resolve。
✅ 验证方法:
? 解决方案(Laravel 场景):升级至支持高并发的 Laravel Octane(基于 Swoole 或 RoadRunner):
# 安装 Octanecomposer require laravel/octane# 启动 Octane 服务(替代 php artisan serve)php artisan octane:start --server=swoole
Octane 通过常驻内存的异步事件循环,允许多个 HTTP 请求真正并行处理,彻底解除流式连接对其他请求的阻塞。
⚠️ 其他注意事项:
总结:该问题本质是「前端假死,后端阻塞」。调试此类问题时,应优先排查服务端并发模型,而非怀疑 Axios 或异步语法 —— 流式响应本身不禁止后续请求,但服务器架构决定其是否可达。