js控制并发请求数量

82 阅读1分钟
  function timeout(time) {
    return new Promise((resolve) => {
      setTimeout(() => {
        resolve()
      }, time)
    })
  }

  function addTask(time, name) {
    superTask
      .add(() => timeout(time))
      .then(() => {
        console.log(`任务${name}完成`)
      })
  }

  class SuperTask {
    constructor(parallelCount = 2) {
      this.parallelCount = parallelCount
      //正在运行的任务
      this.runningCount = 0
      this.tasks = []
    }
    add(task) {
      return new Promise((resolve, reject) => {
        //加入列表中,等待调用
        this.tasks.push({ task, resolve, reject })
        //按照逻辑执行
        this._run()
      })
    }
    _run() {
      //运行数量小于限制数量,且任务列表里有任务
      while (this.runningCount < this.parallelCount && this.tasks.length) {
        const { task, resolve, reject } = this.tasks.shift()
        this.runningCount++
        task()
          .then(() => {
            resolve()
          })
          .finally(() => {
            this.runningCount--
            //任何一个任务完成后,都重新调用这个函数,继续执行下个任务
            //因此js是并发,任务还是一个个的执行的
            this._run()
          })
      }
    }
  }
  const superTask = new SuperTask()
  //只有两个任务能执行,其余任务必须等待
  addTask(10000, 1) //10s后输出 任务1
  addTask(5000, 2) //5s后输出 任务2
  addTask(3000, 3) //8s后输出 任务3
  addTask(4000, 4) //12s后输出 任务4
  addTask(5000, 5) //15s后输出 任务5