1. 基本概念
事件循环是JavaScript实现异步编程的核心机制,它负责协调主线程和任务队列,确保JavaScript代码能够非阻塞地执行。
2. 核心组成部分
2.1 调用栈(Call Stack)
- 用于存储正在执行的函数调用
- 遵循后进先出(LIFO)原则
- 当函数执行完毕时,会从栈顶弹出
2.2 任务队列(Task Queue)
- 宏任务队列(Macro Task Queue):setTimeout、setInterval、setImmediate、I/O、UI渲染等
- 微任务队列(Micro Task Queue):Promise.then/catch/finally、process.nextTick、MutationObserver等
3. 事件循环执行流程
1. 执行同步代码(调用栈)
2. 检查微任务队列,执行所有微任务
3. 执行一个宏任务
4. 重复步骤2-3
4. 详细执行顺序
console.log('1'); // 同步代码
setTimeout(() => {
console.log('2'); // 宏任务
}, 0);
Promise.resolve().then(() => {
console.log('3'); // 微任务
});
console.log('4'); // 同步代码
// 输出顺序:1, 4, 3, 25. 关键特点
5.1 微任务优先级高于宏任务
- 每执行完一个宏任务后,会立即检查并执行所有微任务
- 微任务会在下一个宏任务之前执行
5.2 同类型任务按顺序执行
- 宏任务按先进先出(FIFO)顺序执行
- 微任务按先进先出(FIFO)顺序执行
7. 常见面试题示例
7.1 经典题目
console.log('start');
setTimeout(() => {
console.log('timeout1');
Promise.resolve().then(() => {
console.log('promise1');
});
}, 0);
Promise.resolve().then(() => {
console.log('promise2');
setTimeout(() => {
console.log('timeout2');
}, 0);
});
console.log('end');
// 输出:start, end, promise2, timeout1, promise1, timeout2