- JS实现一个带并发限制的异步调度器Scheduler,保证同时运行的任务最多有两个。完善下面代码的Scheduler类,使以下程序能够正常输出:
class Scheduler {
add(promiseCreator) { ... }
// ...
}
const timeout = time => new Promise(resolve => {
setTimeout(resolve, time);
})
const scheduler = new Scheduler();
const addTask = (time,order) => {
scheduler.add(() => timeout(time).then(()=>console.log(order)))
}
addTask(1000, '1');
addTask(500, '2');
addTask(300, '3');
addTask(400, '4');
// output: 2 3 1 4
class Scheduler {
executeQueue = [];
waitQueue = [];
exeCount = 0;
add(promiseCreator) {
if (this.executeQueue.length >= 2) {
//超过两个时,等待
this.waitQueue.push(promiseCreator);
return;
}
// 不足2个时入队
this.executeQueue.push(promiseCreator);
this.execute();
}
execute() {
if (this.exeCount >= 2) {
return;
}
this.exeCount++;
let p = this.executeQueue.shift();
p()
.then(
(res) => {
this.exeCount--;
if (this.waitQueue.length > 0) {
this.executeQueue.push(this.waitQueue.shift());
}
if (this.executeQueue.length > 0) {
this.execute();
}
},
(rej) => {
//把异常抛出来让外部catch到
throw new Error(rej);
}
)
.catch((err) => {
console.log(err);
this.exeCount--;
if (this.waitQueue.length > 0) {
this.executeQueue.push(this.waitQueue.shift());
}
if (this.executeQueue.length > 0) {
this.execute();
}
});
}
}
const timeout = (time) =>
new Promise((resolve, rejects) => {
if (time === 300) {
rejects(new Error("xx"));
} else {
setTimeout(resolve, time);
}
});
const scheduler = new Scheduler();
const addTask = (time, order) => {
scheduler.add(() => timeout(time).then(() => console.log(order)));
};
addTask(1000, "1");
addTask(500, "2");
addTask(300, "3");
addTask(400, "4");
// scheduler.taskStart();
// normal output: 2 3 1 4
// error output: 2 Error 4 1