• Vue并发队列-最大并发数量限制


    需求:

    • 设置最大请求数量,当前请求数量,待执行队列
    • 调用时,创建一个新任务,然后判断是否达到最大请求数量,若达到则将任务追加到待执行队列,否则,则直接执行该任务。并返回Promise
    • 建任务时,需要返回一个函数,当该任务开始执行则当前数量加一。当任务执行完毕时使用finally,当前数量减一,并从待执行队列中取出新任务执行

    实现:

    /* eslint-disable */
    export class LimitPromise {
      constructor (max) {
        // 异步任务“并发”上限
        this._max = max
        // 当前正在执行的任务数量
        this._count = 0
        // 等待执行的任务队列
        this._taskQueue = []
      }
    
      /**
         * 调用器,将异步任务函数和它的参数传入
         * @param caller 异步任务函数,它必须是async函数或者返回Promise的函数
         * @param args 异步任务函数的参数列表
         * @returns {Promise<unknown>} 返回一个新的Promise
         */
      call (caller, ...args) {
        return new Promise((resolve, reject) => {
          const task = this._createTask(caller, args, resolve, reject)
          if (this._count >= this._max) {
            // console.log('count >= max, push a task to queue')
            this._taskQueue.push(task)
          } else {
            task()
          }
        })
      }
    
      /**
         * 创建一个任务
         * @param caller 实际执行的函数
         * @param args 执行函数的参数
         * @param resolve
         * @param reject
         * @returns {Function} 返回一个任务函数
         * @private
         */
      _createTask (caller, args, resolve, reject) {
        return () => {
          // 实际上是在这里调用了异步任务,并将异步任务的返回(resolve和reject)抛给了上层
          caller(...args)
            .then(resolve)
            .catch(reject)
            .finally(() => {
              // 任务队列的消费区,利用Promise的finally方法,在异步任务结束后,取出下一个任务执行
              this._count--
              if (this._taskQueue.length) {
                // console.log('a task run over, pop a task to run')
                let task = this._taskQueue.shift()
                task()
              } else {
                // console.log('task count = ', count)
              }
            })
          this._count++
          // console.log('task run , task count = ', count)
        }
      }
    }

    使用:

    假设我们有一个请求方法this.$http.post方法,一般情况下,是这样使用的

    function requestDemo(){
        this.$http.post('/xxx/xxx').then(({ data: res }) => {
            //处理返回结果
        }).catch((err) => {
            //处理异常情况
        })
    }

    现在我们要把它改造成受限制的网络请求,假设并发请求上限设为10个,并起名叫limitRequest.js。实现如下:

     
    // 并发队列
    import { LimitPromise } from '@/utils/limit-promise.js'
    // 请求上限
    const MAX = 10
    // 核心控制器
    const limitP = new LimitPromise(MAX)
    //请求方法
    function requestDemo(){
      this.$http.post('/xxx/xxx').then(({ data: res }) => {
            //处理返回结果
        }).catch((err) => {
            //处理异常情况
        })
    }
    //执行
    function run(){
      for(let i=0;i<100;i++){
        // 上传 
        limitP.call(this.requestDemo, params1,params2)
      }
    }

    参考:https://www.jianshu.com/p/cc706239c7ef

  • 相关阅读:
    整站爬虫命令
    小故事集锦
    中国最经典广告语大全
    常用的正则表达式
    特殊成员方法
    使用super函数----增量重写普通方法和构造方法
    重写普通方法和构造方法------原类的方法会被覆盖
    Python的数据类型与数据结构
    类和对象
    生产者-消费者问题与quene模块
  • 原文地址:https://www.cnblogs.com/sunshouguo/p/14844338.html
Copyright © 2020-2023  润新知