如何限制 Ajax 并发请求数量避免浏览器卡死?

Good“嘉木 阅读 4

我正在做一个图片上传功能,用户一次能选几十张图,我用 Promise.all 发起并发请求,结果浏览器直接卡住了,甚至有些请求失败了。试过自己写队列控制,但逻辑太乱没搞定。

是不是应该限制同时进行的请求数量?比如最多只允许 3 个请求同时跑?有没有简单又靠谱的做法?

.upload-item {
  width: 100px;
  height: 100px;
  border: 1px dashed #ccc;
  display: inline-block;
  margin: 5px;
}
.uploading {
  opacity: 0.6;
}
我来解答 赞 6 收藏
二维码
手机扫码查看
1 条解答
红爱 Dev
你这情况我遇到过,几十张图一起扔给浏览器,它不卡谁卡。浏览器的 HTTP 并发限制本来就有限,Chrome 同域名也就 6 个连接左右,你 Promise.all 一下全发出去,请求队列直接爆了。

前端这块做并发控制,核心思路就是搞个"调度器",维护一个等待队列,同时跑的请求不超过你设定的阈值。

给你写个简单实用的并发控制类:

class ConcurrencyLimit {
constructor(max) {
this.max = max
this.running = 0
this.queue = []
}

run(fn) {
return new Promise((resolve, reject) => {
const task = () => {
this.running++
fn()
.then(resolve)
.catch(reject)
.finally(() => {
this.running--
this.next()
})
}

if (this.running < this.max) {
task()
} else {
this.queue.push(task)
}
})
}

next() {
while (this.running < this.max && this.queue.length) {
const task = this.queue.shift()
task()
}
}
}


使用的时候也很简单,假设你有个上传函数 uploadFile

const limiter = new ConcurrencyLimit(3) // 最多3个并发

const tasks = fileList.map(file =>
limiter.run(() => uploadFile(file))
)

Promise.all(tasks).then(results => {
console.log('全部上传完成', results)
}).catch(err => {
console.error('有上传失败的', err)
})


这样不管用户选多少张图,同时跑的请求永远只有 3 个,一个完成了才会从队列里拉下一个出来执行。浏览器压力小了,页面也不卡了,请求成功率也上去了。

并发数设多少合适?一般 3 到 5 个就够用了,太大意义不大,还可能被后端限流或者触发 429。
点赞
2026-03-02 19:02