任务队列,控制最大并发量

249 阅读1分钟

设计一个任务队列,控制最大并发量

// 生成任务队列
function createTask(i: Number): () => Promise<Number> {
  return () => {
    return new Promise((resolve) => {
      setTimeout(() => resolve(i), 1000);
    });
  };
}


class TasksQueue {
  max: number;
  taskList: Array<() => Promise<Number>>;
  constructor() {
    this.max = 10;
    this.taskList = [];
    // 使用异步,自动执行
    setTimeout(() => {
      this.run();
    }, 1000);
  }

  add(task: () => Promise<Number>) {
    this.taskList.push(task);
  }

  run() {
    const length = this.taskList.length;
    if (!length) return;
    const min = Math.min(length, this.max);
    for (let i = 0; i < min; i++) {
    // task 是这种形式  (i)=>Promise.resolve(i)
      const task = this.taskList.shift();
      // 重要 就是为了占位 tag1
      this.max--;
      if (task) {
        task()
          .then((res) => {
            console.log(res);
          })
          .catch((err) => {
            console.log(err);
          })
          .finally(() => {
          // 重要 tag1
            this.max++;
            this.run();
          });
      }
    }
  }
}
let taskQueue = new TasksQueue();
// 0-39 个函数
for (let i = 0; i < 40; i++) {
  const task = createTask(i);
  taskQueue.add(task);
}

note:tag1 是非常重要的,他代表了一个执行函数,如果没有,由于 for 循环是同步执行,当其中一个 for 0 循环完毕,他会立即执行 run 方法,按照图中所示,当第一次for 循环结束后,会有 10个在执行,第二次执行完,如果 有两个 Promise 走完,会同时有 20个 在执行,会大于 taskList的长度,来自 B站 time:2022.5.16 22:09