2025年09月09日/ 浏览 7
在现代前端开发中,任务调度(Scheduler)是实现复杂业务逻辑的重要手段。简单来说,调度就是控制不同任务按照特定顺序和优先级执行的机制。JavaScript作为单线程语言,其调度实现有着独特的设计模式。
常见的调度场景包括:
– 异步任务队列管理
– 高优先级任务插队
– 资源密集型任务分片执行
– 动画帧率控制
JavaScript最基础的调度方式是利用事件循环机制:
javascript
function scheduleTask(task) {
setTimeout(task, 0);
}
这种简单调度将任务放入宏任务队列,适合不紧急的后台操作。
对于需要更高优先级的任务,可以使用微任务队列:
javascript
function highPriorityTask(task) {
Promise.resolve().then(task);
}
对于非关键任务,可以使用requestIdleCallback
:
javascript
function scheduleBackgroundTask(task) {
requestIdleCallback(task, { timeout: 100 });
}
下面是一个支持优先级的多任务调度器实现:
javascript
class Scheduler {
constructor(concurrency = 2) {
this.queue = [];
this.running = 0;
this.concurrency = concurrency;
}
add(task, priority = 0) {
const job = { task, priority };
let index = this.queue.findIndex(
item => item.priority < priority
);
index = index === -1 ? this.queue.length : index;
this.queue.splice(index, 0, job);
this.run();
}
run() {
while (
this.running < this.concurrency &&
this.queue.length
) {
const { task } = this.queue.shift();
this.running++;
Promise.resolve(task()).finally(() => {
this.running--;
this.run();
});
}
}
}
通过setTimeout
或requestAnimationFrame
将长任务分解:
javascript
function timeSlicing(task, duration = 50) {
let deadline = performance.now() + duration;
function next() {
while (performance.now() < deadline) {
if (task.next().done) return;
}
requestIdleCallback(next);
}
next();
}
根据运行时条件动态改变任务优先级:
javascript
function dynamicPriorityScheduler() {
// 根据设备性能、电量等动态调整
const basePriority = navigator.hardwareConcurrency > 4 ? 1 : 0;
// ...具体实现
}
实现调度系统时需要注意:
– 避免调度器本身成为性能瓶颈
– 合理设置默认并发数(通常4-6个)
– 添加任务超时处理机制
– 考虑内存泄漏风险,及时清理已完成任务