前言
前端并发请求数量控制是指在客户端(通常是在浏览器中)管理和控制同时发出的异步请求的数量。在进行网络请求,如使用 AJAX 与服务器交互时,可能会有多个请求同时发送。如果不加以控制,大量并发的请求可能会导致服务器压力过大,或者在客户端造成性能问题。
场景
公司有一个发票管理模块,实现了用户上传单张发票,系统进行切割,ocr识别,验真,验重,保存。现在需要实现批量操作:同时上传多张发票图片,进行自动进行上述操作。并且完成一张即在列表中展示一张出来。最终定的方案是前端循环去一次调用上述流程的接口,因此这里就需要实现一个线程池,,请求中的数据达到最大值时,将所有请求添加到队列中进行排队,每当有一个请求返回,就留下一个空位,可以去处理队列中的首位执行请求。
实现
js
class LimitPromise{
constructor(max){
this._max = max || 6 // 最大执行数量
this._count = 0 // 当前执行的数量
this._taskQueue = [] // 队列
this.instance = null // 实例 单例模式
}
run(caller){
return new Promise((resolve, reject)=>{
const task = this._createTask(caller, resolve, reject)
// 当前执行的数量 > 最大执行数量,就加入队列排队;否则直接执行
if(this._count >= this._max){
this._taskQueue.push(task)
}else {
task()
}
})
}
_createTask(caller, resolve, reject){
return ()=> {
caller().then(res =>{
resolve(res)
}).catch(err => {
reject(err)
}).finally(()=>{
// 执行完成
this._count--
if(this._taskQueue.length > 0){
// 取出队列中的首位执行
const task= this._taskQueue.shift()
task()
}
})
this._count++
}
}
static getInstance(max){
if(!this.instance){
this.instance = new LimitPromise(max)
}
return this.instance
}
}
如何使用
js
// 构获取实例
const limitPromise = LimitPromise.getInstance(3)
const asyncTask = (params) => {
return new Promise((resolve, reject)=>{
setTimeout(() => {
if (params % 2 == 0) {
resolve({
tag:'成功了', params
})
} else {
reject({
tag:'失败了', params
})
}
}, 1000)
})
}
for(let i=0; i<= 100; i++){
limitPromise.run(() => asyncTask(i)).then(
result => {
console.log('result', result)
},
error => {
console.log('error', error)
}
)
}