并发任务队列(字节青训测试题)

需求描述

封装一个并发任务队列类,用于对一些异步任务按指定的并发数量进行并发执行。

/**
 * 延迟函数
 * @param {number} time - 延迟时间
 * @return {Promise} delayFn - 延迟函数(异步封装)
 */
function timeout(time) {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve();
    }, time)
  });
}

// 并发任务队列,接收一个最大并发数量
const concurrentTaskQueue = new ConcurrentTaskQueue(2);

/**
 * 添加并发任务并按规则执行
 * @param {number} time - 延迟时间
 * @param {string} name - 任务名称
 */
function addTask(time, name) {
  concurrentTaskQueue.add(() => timeout(time)).then(() => {
    console.log(`任务${name}完成`);
  })
}

addTask(1000, 1);
addTask(1000, 2);
addTask(1000, 3);
addTask(1000, 4);
addTask(1000, 5);

实现

// 并发任务队列
class ConcurrentTaskQueue {
  constructor(concurrentCount) {
    this.concurrentCount = concurrentCount; // 并发数量
    this.tasks = []; // 任务队列
    this.runningCount = 0; // 正在执行的任务数量
  }
  // 添加任务
  add(task) {
    return new Promise((resolve) => {
      this.tasks.push({ task, resolve});
      this.handle(); // 添加完立即执行
    })
  }
  // 执行任务
  handle() {
    if (this.runningCount < this.concurrentCount && this.tasks.length > 0) {
      const { task, resolve} = this.tasks.shift(); // 取出任务
      this.runningCount++;
      task().then(resolve).finally(() => {
        this.runningCount--;
        this.handle(); // 执行完毕,并发数量有空余,再次调用
      })
    }
  }
}

你可能感兴趣的:(JS,前端,javascript,异步,promise,并发任务队列)