js实现eventloop
实现 JavaScript Event Loop
JavaScript 的 Event Loop 是其异步编程的核心机制。以下是实现 Event Loop 的关键步骤:
理解 Event Loop 的基本结构
Event Loop 由调用栈(Call Stack)、任务队列(Task Queue)和微任务队列(Microtask Queue)组成。调用栈负责执行同步代码,任务队列存放宏任务(如 setTimeout),微任务队列存放微任务(如 Promise)。
模拟调用栈和队列
创建一个简单的调用栈和队列结构来模拟 Event Loop 的行为:
const callStack = [];
const macroTaskQueue = [];
const microTaskQueue = [];
处理同步代码
同步代码直接推入调用栈并执行:
function executeSyncCode(task) {
callStack.push(task);
console.log(`Executing: ${task}`);
callStack.pop();
}
处理异步代码
异步任务(如 setTimeout)被推入宏任务队列:
function setTimeoutAsync(callback, delay) {
macroTaskQueue.push(() => {
setTimeout(() => {
callStack.push(callback);
callback();
callStack.pop();
}, delay);
});
}
处理微任务
微任务(如 Promise)被推入微任务队列,并在当前宏任务执行完成后立即执行:
function promiseAsync(callback) {
microTaskQueue.push(() => {
Promise.resolve().then(() => {
callStack.push(callback);
callback();
callStack.pop();
});
});
}
Event Loop 主循环
实现一个简单的 Event Loop 主循环,优先处理微任务队列,再处理宏任务队列:
function eventLoop() {
while (microTaskQueue.length > 0) {
const task = microTaskQueue.shift();
task();
}
if (macroTaskQueue.length > 0) {
const task = macroTaskQueue.shift();
task();
}
if (callStack.length === 0 && macroTaskQueue.length === 0 && microTaskQueue.length === 0) {
console.log("Event Loop idle");
return;
}
setTimeout(eventLoop, 0);
}
示例用法
以下代码演示了如何使用上述实现的 Event Loop:
executeSyncCode(() => console.log("Sync Task 1"));
setTimeoutAsync(() => console.log("Macro Task 1"), 1000);
promiseAsync(() => console.log("Micro Task 1"));
executeSyncCode(() => console.log("Sync Task 2"));
eventLoop();
输出顺序
运行上述代码后,输出顺序为:

Sync Task 1
Sync Task 2
Micro Task 1
Macro Task 1
Event Loop idle
关键点
- 微任务队列优先级高于宏任务队列。
- 每次宏任务执行完成后,会清空微任务队列。
setTimeout和Promise是典型的宏任务和微任务。
通过以上实现,可以清晰地理解 JavaScript Event Loop 的工作机制。






