eventloop js实现
Event Loop 的基本概念
Event Loop 是 JavaScript 处理异步任务的核心机制,它通过任务队列和调用栈的协作实现非阻塞执行。其核心分为宏任务(macrotask)和微任务(microtask),执行顺序遵循“一个宏任务 → 所有微任务”的循环。
宏任务与微任务
宏任务包括:
setTimeout、setInterval- I/O 操作(如文件读取)
- UI 渲染
setImmediate(Node.js)
微任务包括:
Promise.then、Promise.catchMutationObserverprocess.nextTick(Node.js,优先级高于其他微任务)
简单 Event Loop 实现示例
以下是一个简化版的 Event Loop 模拟代码,展示如何调度宏任务和微任务:
class EventLoop {
constructor() {
this.macroTaskQueue = []; // 宏任务队列
this.microTaskQueue = []; // 微任务队列
this.isRunning = false;
}
// 添加宏任务
addMacroTask(task) {
this.macroTaskQueue.push(task);
this.runLoop();
}
// 添加微任务
addMicroTask(task) {
this.microTaskQueue.push(task);
this.runLoop();
}
// 执行事件循环
runLoop() {
if (this.isRunning) return;
this.isRunning = true;
while (true) {
// 执行所有微任务
while (this.microTaskQueue.length > 0) {
const task = this.microTaskQueue.shift();
task();
}
// 执行一个宏任务
if (this.macroTaskQueue.length > 0) {
const task = this.macroTaskQueue.shift();
task();
} else {
break; // 队列为空时退出
}
}
this.isRunning = false;
}
}
// 使用示例
const loop = new EventLoop();
loop.addMacroTask(() => console.log("宏任务 1"));
loop.addMicroTask(() => console.log("微任务 1"));
loop.addMacroTask(() => console.log("宏任务 2"));
loop.addMicroTask(() => console.log("微任务 2"));
// 输出顺序:
// 宏任务 1
// 微任务 1
// 微任务 2
// 宏任务 2
Node.js 与浏览器的差异
-
Node.js:
process.nextTick的优先级高于Promise。setImmediate在 I/O 阶段后执行,setTimeout在定时器阶段执行。
-
浏览器:

requestAnimationFrame是特殊的宏任务,在渲染前执行。- 微任务执行时机可能在渲染之前或之后,取决于浏览器实现。
实际应用注意事项
- 避免阻塞微任务队列:长时间运行的微任务会延迟渲染和后续任务。
- 宏任务的拆分:对于耗时操作,使用
setTimeout或requestIdleCallback分片执行。 - 优先级控制:在 Node.js 中,高优先级任务用
process.nextTick,普通异步用Promise。
通过理解 Event Loop 的调度机制,可以优化代码性能并避免常见的异步陷阱。






