francecil / leetcode

solutions about leetcode
MIT License
9 stars 1 forks source link

JS 实现带并发限制的异步任务队列 #65

Closed francecil closed 1 year ago

francecil commented 1 year ago

实现一个异步队列 AsyncQueue ,仅允许同时执行 n 个任务,参考如下示例

const asyncQueue = new AsyncQueue(2); // 最多同时执行2个任务

for (let i = 1; i <= 5; i++) {
  asyncQueue.push(async () => {
    console.log(`Task ${i} started`);
    await delay(1000);
    console.log(`Task ${i} completed`);
  });
}

function delay(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

预期输出如下:

Task 1 started
Task 2 started
Task 1 completed
Task 3 started
Task 2 completed
Task 4 started
Task 3 completed
Task 5 started
Task 4 completed
Task 5 completed
francecil commented 1 year ago
class AsyncQueue {
  constructor(concurrent) {
    /** 可同时执行的任务数 */
    this.concurrent = concurrent
    /** 存放待执行的任务 */
    this.queue = []
    /** 当前正在执行的任务数 */
    this.runningTasks = 0
  }

  push(job) {
    if(this.runningTasks < this.concurrent) {
      this.runningTasks ++ 
      this.runTask(job)
    } else {
      // 达到最大并发次数,放入队列
      this.queue.push(job)
    }
  }
  next() {
    const headTask = this.queue.shift()
    if(headTask) {
      this.runTask(headTask)
    }
  }
  async runTask(job) {
    try {
      await job()
    } catch (error) {
      console.log(error)
    }
    this.runningTasks--
    this.next()
  }
}