前端如何实现并发请求数量控制?

前言

前端并发请求数量控制是指在客户端(通常是在浏览器中)管理和控制同时发出的异步请求的数量。在进行网络请求,如使用 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)
        }
    )
}
相关推荐
前端大白话16 分钟前
救命!这10个Vue3技巧藏太深了!性能翻倍+摸鱼神器全揭秘
前端·javascript·vue.js
嘻嘻嘻嘻嘻嘻ys18 分钟前
《Vue 3全栈架构实战:Vite工程化、Pinia状态管理与Nuxt 3深度解析》
前端·后端
前端大白话20 分钟前
前端人必看!10个JavaScript“救命”技巧,让你告别加班改Bug
前端·javascript·程序员
cg501730 分钟前
Vue回调函数中的this
前端·javascript·vue.js
前端太佬32 分钟前
从零到一实现扫码登录:一个前端菜鸟的踩坑实录
前端·javascript·架构
yuanmenglxb200443 分钟前
微信小程序核心技术栈
前端·javascript·vue.js·笔记·微信小程序·小程序
爱编程的鱼43 分钟前
如何让 HTML 文件嵌入另一个 HTML 文件:详解与实践
前端·html
_09271 小时前
Vue 2 与 Vue 3 的核心区别及 Vue 3 新特性详解
前端
David凉宸1 小时前
一文带你使用Vue完成移动端(apk)项目
前端
会飞的鱼先生1 小时前
Vue3的内置组件 -实现过渡动画 TransitionGroup
前端·javascript·vue.js·vue