js-异步任务并发控制

文章介绍了一个用于控制大型项目中大量TCP请求并发的解决方案。通过创建一个并发任务队列类`ParallelTaskList`,限制最大并发数,使用先进先出的策略执行任务,确保不会阻塞其他资源请求。该类提供了添加单个任务和批量添加任务的方法,并在任务执行完毕后自动调度下一个任务。
摘要由CSDN通过智能技术生成

背景

在比较大型的项目中,可能需要一次性发送几十上百次的请求,如此规模的TCP连接建立,可能会阻塞其他的资源请求,需要控制请求的并发数量,避免此问题。

分析

  1. 确认最大并发数
  2. 使用队列的数据格式来缓存任务,因为任务执行顺序是先进先出的
  3. 定义一个运行函数,当最大并发数 < 当前运行数 && 任务队列不为空时,取出列表的第一项任务执行
  4. 提供一个添加任务的方法

实现

// 并发任务队列
class ParallelTaskList {
  // 最大并发数
  parallelCount = 0
  // 总任务数
  tasksCount = 0
  // 任务队列
  tasks = []
  constructor(parallelCount = 2) {
    this.parallelCount = parallelCount
  }
  // 添加任务
  add(task) {
    return new Promise((resolve, reject) => {
      // 添加任务到队列中
      this.tasks.push({
        task,
        resolve,
        reject
      })
      // 运行任务
      this._run()
    })
  }
  // 批量添加任务
  batchAdd(taskList) {
    taskList.forEach((task) => this.add(task))
  }
  // 依次运行任务队列中的所有任务
  _run() {
    if (this.runningCount < this.parallelCount && this.tasks.length) {
      // 正在运行的数量+1
      this.runningCount++
      // 队列先进先出原则,取出任务队列中的第一项任务
      const { task, resolve, reject } = this.tasks.shift()
      // 执行任务
      task()
        .then(resolve, reject)
        .finally(() => {
          // 执行完毕后,正在运行的数量-1
          this.runningCount--
          // 递归调用
          this._run()
        })
    }
  }
}

调用

function task1() {
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log('任务1执行完毕')
      resolve()
    }, 1000)
  })
}
function task2() {
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log('任务2执行完毕')
      resolve()
    }, 4000)
  })
}
function task3() {
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log('任务3执行完毕')
      resolve()
    }, 4000)
  })
}

// 实例化
const parallelTaskList = new ParallelTaskList()
parallelTaskList.add(task1) // 1秒后执行完毕
parallelTaskList.add(task2) // 4秒后执行完毕
parallelTaskList.add(task3) // 5秒后执行完毕(任务1执行后执行该任务,1+4=5)
// parallelTaskList.batchAdd([task1, task2, task3])
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值