1️⃣ pending 的基本含义
-
pending表示请求已经发出,但还没有收到服务器响应。 -
对于分片上传来说,每个块都是一个独立的请求(XHR 或 fetch / Axios)。
-
在浏览器网络面板里,如果请求显示为
pending,说明:- 浏览器已经开始发送这个分片数据(可能还在上传中)
- 服务器还没有返回响应(200/500/其它)
-
它不是错误,只是表示请求还在进行中。
2️⃣ 分片上传中为什么会看到 pending
分片上传通常是大文件分多块上传,每块可能几 MB:
- 网络上传时间长 → 请求还没完成 → 状态显示为
pending - 并发上传多个分片 → 多个请求同时
pending - 如果服务器处理慢,或者网络不稳定,也会让请求长时间
pending
简单类比:
pending就像你给快递下单了,快递员还没送到家,你还在等待快递状态更新。
3️⃣ 状态流
对于每个分片请求:
- pending → 请求发送中
- stalled/waiting → 网络延迟或服务器处理慢
- 200/201 → 上传成功,浏览器收到响应
- 4xx/5xx → 上传失败,需要重试
4️⃣ 注意事项
-
如果很多请求长时间
pending,可能是:- 服务器处理慢或阻塞
- 上传的文件块太大
- 并发上传数量太多(浏览器限制每个域名最大并发请求,一般 6~10 个)
-
分片上传优化:
- 限制并发上传块数量(例如 3~5 个同时上传)
- 合理分块大小(通常 1~5MB)
- 在前端设置超时或重试机制
🧩 一、背景:浏览器的并发限制
浏览器在网络层(HTTP/HTTPS)中,为了避免资源竞争、节流带宽,对同一个域名的并发连接数是有限制的。
一般是:
| 浏览器 | 每个域名的并发限制 |
|---|---|
| Chrome / Edge | ~6 |
| Firefox | ~6 |
| Safari | ~6 |
| 老版 IE | 4 |
也就是说:
对同一个服务器(域名),浏览器最多只能同时维持 6 个请求。
📦 二、当你上传大文件时
如果你把一个大文件拆成很多块(比如 100 块),然后直接这样并发上传:
for (let i = 0; i < 100; i++) {
uploadChunk(i); // 每个 uploadChunk 都是一个 fetch / xhr
}
那会发生什么?
- 浏览器会立刻尝试发出 100 个请求;
- 前 6 个进入**“正在上传”状态**;
- 剩下 94 个会被放进请求队列(排队等待) ;
- 当前面的请求完成后,新的才会被“接力”发出去。
🔥 三、这会带来什么问题?
1️⃣ 页面卡顿 / UI 延迟
- 如果你没正确处理异步队列、或者没有让事件循环喘息(比如
await Promise.race控制节奏),
浏览器主线程会因为大量任务排队,导致 UI 卡顿。
2️⃣ 进度条不准
- 太多请求排队在浏览器内部队列中,onprogress / upload.onprogress 不会立即触发。
你会以为“卡住了”,其实只是还没轮到上传。
3️⃣ 请求失败或被中止
- 某些浏览器或服务器会中止超出连接数的请求;
- 有时服务器也有限流策略(比如 Nginx、OSS、S3 等会限制同一 IP 同时上传数)。
4️⃣ 串口“堵死”
- 如果页面上还有别的请求(例如接口轮询、心跳、WebSocket reconnect),
它们也可能因为连接被占满而卡住。
🧩 四、正确做法:控制并发数
👉 这时我们就要用前面那个函数:
async function concurrentUpload(tasks, concurrency = 3) {
const results = [];
const executing = new Set();
for (const task of tasks) {
const p = Promise.resolve().then(task);
results.push(p);
executing.add(p);
const clean = () => executing.delete(p);
p.then(clean).catch(clean);
if (executing.size >= concurrency) {
await Promise.race(executing);
}
}
return Promise.all(results);
}
使用方式:
const tasks = chunks.map((chunk, i) => () => uploadChunk(chunk, i));
concurrentUpload(tasks, 3);
🔹 优点:
- 永远只会占用 3 个 HTTP 连接;
- 有任务完成后再补新的;
- 进度更新平滑;
- 页面不卡;
- 上传性能反而更稳定。