使用 Promise.all + fetch 在控制台快速验证并发请求
使用 Promise.all + fetch 在控制台快速验证并发请求
在前端调试或接口联调阶段,我们经常会遇到这样的问题:
多个接口是否真的并发执行? 某个接口变慢 / 报错,是否会影响其他请求?
浏览器控制台其实是一个非常适合做并发测试的地方。本文通过一个极简、实用的 Promise.all + fetch 模式,来系统梳理如何正确地在控制台验证并发请求行为。
一、最核心的并发测试写法
推荐的标准写法如下:
1
2
3
4
5
6
7
8
9
10
11
const [resA, resB] = await Promise.all([
fetch('/api/a'),
fetch('/api/b')
]);
const [dataA, dataB] = await Promise.all([
resA.json(),
resB.json()
]);
console.log(dataA, dataB);
这一段代码非常适合直接粘到 DevTools 控制台中执行,用于快速验证多个接口的并发行为。
二、这段代码到底做了什么?
我们可以把它拆成两个阶段来看。
1️⃣ 第一阶段:并发发起请求(I/O 并发)
1
2
3
4
await Promise.all([
fetch('/api/a'),
fetch('/api/b')
]);
这一行的关键点是:
- 两个
fetch同时创建并立即发起请求 - 不存在“等 A 完成再请求 B”的情况
- 网络面板中可以看到两个请求几乎同时进入 Pending 状态
⚠️ 对比一个常见的“伪并发”写法:
1
2
await fetch('/api/a');
await fetch('/api/b');
上面的代码是严格串行的,只能用于顺序依赖场景,不适合做并发验证。
2️⃣ 第二阶段:并发解析响应体(CPU / 内存阶段)
1
2
3
4
await Promise.all([
resA.json(),
resB.json()
]);
这一点经常被忽略,但非常重要:
response.json()本身也是异步操作- 如果接口返回体较大,JSON 解析也可能成为性能瓶颈
- 同样可以(也应该)并发处理
通过拆成两个 Promise.all,可以清晰地区分:
| 阶段 | 并发内容 |
|---|---|
| 第一段 | 网络请求并发 |
| 第二段 | 响应解析并发 |
这在性能分析和问题定位时非常有价值。
三、为什么这种写法特别适合“并发测试”?
✅ 1. 语义非常清晰
- 并发点非常明确
- 没有隐藏的 await
- 一眼就能看出是否存在串行逻辑
✅ 2. 非常适合控制台快速验证
特点包括:
- 不依赖框架
- 不依赖构建
- 不需要额外封装
- 复制即用
在排查:
- 后端接口性能
- 网关限流
- 并发冲突
- 请求是否被浏览器阻塞
这些问题时,效率极高。
✅ 3. 与 Network 面板高度契合
配合 Chrome DevTools → Network:
- 可以直观看到请求是否“同时 Pending”
- 可以判断是否被 CORS / HTTPS / Mixed Content 拦截
- 可以对比并发 vs 串行的耗时差异
这是后端 / 前端联调时非常好用的一种方式。
四、需要注意的一个“坑”:Promise.all 的失败行为
Promise.all 有一个非常重要的特性:
只要其中一个 Promise 失败,整体立即 reject
例如:
/api/a成功返回/api/b网络失败(Failed to fetch)
结果是:
- A 实际已经请求成功
- 但整体代码直接抛异常
如果你的测试目标是:
“看看哪些成功,哪些失败”
那么可以使用:
1
2
3
4
5
6
const results = await Promise.allSettled([
fetch('/api/a'),
fetch('/api/b')
]);
console.log(results);
这在排查并发异常场景时尤其有用。
五、适用场景总结
这种写法非常适合用于:
- 并发接口测试
- 接口性能对比
- 验证是否被浏览器层拦截
- 调试后端限流 / 并发控制
- 博客或技术分享中的示例代码
同时,它也完全可以迁移到实际业务代码中使用。
六、一句话总结
在控制台中验证并发请求,最清晰、最可靠的方式,就是:
await Promise.all([ fetchA, fetchB ])
结构清晰、行为确定、调试友好,非常值得作为一个“并发测试模板”长期保留。
本文由作者按照 CC BY 4.0 进行授权