调度器
2024年04月08日
一、认识
在调度器中,我们需要维护一个任务队列,当任务完成后,调度器从队列中取出下一个任务并执行。如果同时允许多个任务并行执行,我们可以使用一个计数器来控制并发数。
二、实现
class Scheduler {
constructor(parallelism) {
this.queue = [];
this.runningTask = 0;
this.parallelism = parallelism;
}
add(task, callback) {
return new Promise((resolve, reject) => {
const taskItem = {
reject,
resolve,
callback,
processor: () => Promise.resolve().then(() => task())
};
this.queue.push(taskItem);
this.schedule();
});
}
schedule() {
while (this.runningTask < this.parallelism && this.queue.length) {
this.runningTask++;
const taskItem = this.queue.shift();
const { processor, resolve, reject, callback } = taskItem;
processor()
.then(res => {
resolve && resolve(res);
callback && callback(null, res);
})
.catch(error => {
reject && reject(error);
callback && callback(error, null);
})
.finally(() => {
this.runningTask--;
this.schedule();
});
}
}
}
三、测试
const scheduler = new Scheduler(2);
function request(timeout) {
return new Promise(resolve => {
setTimeout(() => {
resolve(timeout);
}, timeout);
});
}
function addTask(timeout) {
scheduler
.add(
() => request(timeout),
(error, result) => {
console.log('result', result);
if (result === 3000) {
console.timeEnd('timer');
}
}
)
.then(result => {
// console.log('result', result);
// if (result === 3000) {
// console.timeEnd('timer');
// }
});
}
console.time('timer');
addTask(1000);
addTask(2000);
addTask(3000);
addTask(4000);