[JS面试题]面试官:实现一个调度器,最多只能同时有两个任务同时进行

这个调度器的工作方式是,它会持续检查任务队列,并且每次最多启动两个任务。当一个任务完成(无论是成功还是失败)时,它会立即尝试启动下一个任务,直到队列中没有任务或者达到最大并发数的限制。这种模式在处理I/O密集型任务或者需要限制资源使用的场景中非常有用。

// 实现一个调度器,最多只能同时有两个任务同时进行

interface TaskNode {
  task: any;
  resolve: any;
  reject: any;
}

class SuperTask {
  maxCount = 2;
  taskList: TaskNode[] = [];

  // 进行中的任务数
  runningCount = 0;

  add(task) {
    return new Promise((resolve, reject) => {
      this.taskList.push({
        task,
        resolve,
        reject,
      });

      this._run();
    });
  }

  _run() {
    while (this.runningCount < this.maxCount && this.taskList.length > 0) {
      const { task, resolve, reject } = this.taskList.shift() as TaskNode;

      this.runningCount++;
      task()
        .then(resolve, reject)
        .finally(() => {
          this.runningCount--;
          this._run();
        });
    }
  }
}



const timeout = (time)=>{
  return new Promise<void>((resolve)=>{
    setTimeout(()=>{
      resolve()
    }, time)
  })
}

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

addTask(10000, '任务1'); // 1000毫秒后输出 任务1完成
addTask(5000, '任务2'); // 500毫秒后输出 任务2完成
addTask(3000, '任务3'); // 300毫秒后输出 任务3完成
addTask(4000, '任务4'); // 400毫秒后输出 任务4完成
addTask(5000, '任务5'); // 500毫秒后输出 任务5完成

// 打印顺序
// 任务任务2完成   5s   [1,2]=>[1,3]
// 任务任务3完成   8s   [1,3]=>[1,4]
// 任务任务1完成   10s  [1,4]=>[4,5]
// 任务任务4完成   12s  [4,5]=>[5]
// 任务任务5完成   15s  [5]=>[]

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部