[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]=>[]