跳到主要内容

调度器

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);