JavaScript任务调度器可用queueMicrotask(微任务)、setTimeout(宏任务)及组合实现优先级队列;前者最轻量及时,后者用于延迟执行,组合可区分高优/低优任务。

JavaScript 中可以用事件循环机制配合 setTimeout、Promise.then 或 queueMicrotask 实现一个轻量级任务调度器,核心在于控制任务的执行时机和优先级。
用 queueMicrotask 实现微任务级调度
这是最简洁、语义最清晰的方式,适合需要“在当前同步代码结束后、下次宏任务前”执行的任务。
-
queueMicrotask是原生 API,把回调加入当前 microtask 队列,保证在本轮调用栈清空后立即执行 - 它比
Promise.then更轻量(无需创建 Promise 对象),也比setTimeout(fn, 0)更及时(不进宏任务队列) - 适合做状态更新聚合、防抖中间态、或避免同步阻塞的异步衔接
function scheduleMicro(task) {
queueMicrotask(task);
}
scheduleMicro(() => console.log('微任务1'));
console.log('同步');
// 输出顺序:同步 → 微任务1
用 setTimeout 实现宏任务级延迟调度
当需要将任务推迟到下一轮事件循环(甚至指定毫秒后),setTimeout 是最通用的选择。
详细的 Three.js 3D 图形参考,涵盖场景设置、相机、几何体、材质、光照、动画、控制器、加载器、数学工具和调试。
-
setTimeout(fn, 0)把任务推入宏任务队列,确保它在当前任务及所有微任务执行完后才运行 - 可用于模拟「下一帧」行为、避免长任务阻塞 UI、或实现简单的节流/延迟执行逻辑
- 注意:即使设为 0,实际延迟受浏览器最小间隔限制(通常 ≥ 4ms)
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function runWithDelay() {
console.log('开始');
await delay(100);
console.log('100ms 后执行');
}
组合宏微任务实现优先级队列
真正的调度器常需区分高优(如 UI 更新)与低优(如日志上报)任务,可手动维护两个队列:
立即学习“Java免费学习笔记(深入)”;
- 高优任务用
queueMicrotask推入,保证尽快响应 - 低优任务用
setTimeout(..., 0)推入,让出当前循环给更紧急的操作 - 避免直接递归调用
queueMicrotask(可能造成饥饿),可用标志位+循环消费
class SimpleScheduler {
#microQueue = [];
#macroQueue = [];
#isFlushing = false;
immediate(task) {
this.#microQueue.push(task);
if (!this.#isFlushing) this.#flushMicro();
}
idle(task) {
this.#macroQueue.push(task);
}
#flushMicro() {
this.#isFlushing = true;
while (this.#microQueue.length) {
this.#microQueue.shift()();
}
this.#isFlushing = false;
}
// 可选:在空闲时执行低优任务(配合 requestIdleCallback 更佳)
runIdleTasks() {
if ('requestIdleCallback' in window) {
requestIdleCallback(() => this.#macroQueue.forEach(t => t()));
} else {
setTimeout(() => this.#macroQueue.forEach(t => t()), 0);
}
}
}
注意事项与边界情况
调度器看似简单,但几个细节容易踩坑:
- 不要在微任务中无限添加新微任务,否则会阻塞渲染和事件响应(如未加限制的递归
queueMicrotask) -
Promise.resolve().then()效果等价于queueMicrotask,但开销略大;二者不可混用判断执行顺序 - Node.js 环境中,
process.nextTick比微任务更早执行,仅用于特定底层场景,一般调度器不用它 - 若需精确时间控制(如动画帧对齐),应优先使用
requestAnimationFrame而非定时器

















