Axios Promise.allSettled在Chrome中无法并行执行问题排查
Chrome下同域同URL不同请求头的并行请求串行问题分析与解决
我在ReactJS项目中实现了一套并行请求机制,将请求Promise存入数组后通过Promise.allSettled批量执行,代码如下:
let promises = []; for (const [_, value] of values) { promises.push(axios.get(`https://url`, { timeout: 5000, signal: AbortSignal.timeout(5000), // 5秒后终止请求 headers: {"val": value} })); } const result = await Promise.allSettled(promises)
问题现象
这段逻辑在Firefox中运行正常,但在Chrome中所有请求会串行执行,导致速度极慢,最终因5秒超时限制全部失败。有趣的是,在Chrome开发者工具网络面板勾选「禁用缓存」后,请求会恢复并行执行。
环境信息
- axios版本:1.4.0
- Chrome版本:122.0.6261.128
- Node版本:18.2
补充说明:所有请求的URL完全一致,仅请求头val的值不同;属于同域请求,查看请求时序发现,即便Promise执行器已经运行,请求之间仍会互相等待。
问题根源
Chrome针对同URL、同方法的重复请求存在缓存优化策略:当检测到存在未完成的同URL同方法请求时,会将后续请求放入队列等待前一个请求完成(即使请求头不同),这是浏览器缓存机制引发的串行化行为。勾选「禁用缓存」会绕过该策略,因此请求恢复并行。
解决方案
可以通过以下几种方式打破Chrome的缓存排队机制:
- 给URL添加唯一查询参数
在请求URL后追加不影响业务的唯一参数(如时间戳或随机数),让每个请求的URL唯一,避免触发缓存排队:
promises.push(axios.get(`https://url?_t=${Date.now()}`, { timeout: 5000, signal: AbortSignal.timeout(5000), headers: {"val": value} }));
- 设置请求头强制不缓存
在请求头中添加Cache-Control: no-cache,告知浏览器不对该请求使用缓存策略:
promises.push(axios.get(`https://url`, { timeout: 5000, signal: AbortSignal.timeout(5000), headers: { "val": value, "Cache-Control": "no-cache" } }));
- 自定义axios适配器(进阶)
如果前两种方式不符合业务需求,可以自定义axios的适配器,强制每个请求立即发送。该方式复杂度较高,仅推荐在特殊场景使用。
内容的提问来源于stack exchange,提问作者Rockybilly
相关产品推荐
相关产品推荐

