Event Loop 到底怎么运行?微任务和宏任务的顺序你理解了吗?

26 次浏览次阅读
没有评论

当我们用JavaScript处理异步操作时,setTimeout的回调总比Promise慢半拍?点击按钮后DOM更新为何有时会延迟?这些现象背后都隐藏着Event Loop的运行机制。理解微任务和宏任务的执行顺序,不仅能帮我们写出更高性能的代码,更是通过大厂面试的必备技能。本文将用真实代码示例,带你穿透表象看本质。

一、Event Loop的三大核心规则

1.1 同步代码永远最先执行

所有同步代码都拥有最高优先级,这是Event Loop机制的第一铁律。当遇到函数调用、变量赋值等操作时,引擎会立即执行这些任务,不会给任何异步操作”插队”的机会。

“`javascript
console.log(‘1’); // 同步任务
setTimeout(() => { console.log(‘2’) }, 0); // 宏任务
Promise.resolve().then(() => { console.log(‘3’) }); // 微任务
console.log(‘4’); // 同步任务

// 输出顺序:1 → 4 → 3 → 2
“`

1.2 微任务的”插队特权”

当前宏任务中的微任务会阻塞后续宏任务执行,这是最容易被误解的规则:
1. 执行完所有同步代码
2. 立即清空微任务队列
3. 才会执行下一个宏任务

1.3 宏任务的排队机制

不同类型的宏任务有自己的队列通道:
“`javascript
setTimeout(() => { console.log(‘宏任务1’) }, 0); // 定时器队列
button.addEventListener(‘click’, () => {
console.log(‘宏任务2’)
}); // 交互事件队列
“`

二、微任务与宏任务的本质区别

2.1 微任务(Microtask)的特征

✓ 优先级高于宏任务
✓ 在当前调用栈末尾立即执行
✓ 典型代表:
Promise的.then()/.catch()/.finally()
MutationObserver监听DOM变化
queueMicrotask API

2.2 宏任务(Macrotask)的类型

✓ 每个类型有独立队列
✓ 按事件循环轮次执行
✓ 常见类型包括:
| 类型 | 示例 | 执行优先级 |
||||
| 用户交互 | 点击/滚动事件 | 最高 |
| 网络请求 | fetch回调 | 中 |
| 定时器 | setTimeout | 低 |

三、事件循环的完整执行流程

3.1 浏览器环境下的完整周期

1. 执行当前宏任务(如script标签内容)
2. 清空微任务队列
3. 执行渲染操作(重绘/回流)
4. 执行下一个宏任务

“`javascript
// 经典面试题解析
setTimeout(() => console.log(‘timer’), 0);

Promise.resolve()
.then(() => {
console.log(‘promise1’);
Promise.resolve().then(() => console.log(‘promise2’));
});

// 输出顺序:promise1 → promise2 → timer
“`

3.2 Node.js的特殊情况

process.nextTick优先级高于Promise,这是Node环境与浏览器的核心差异:
“`javascript
Promise.resolve().then(() => console.log(‘promise’));
process.nextTick(() => console.log(‘nextTick’));

// 输出顺序:nextTick → promise
“`

四、实战中的六大注意事项

1. 避免微任务嵌套炸弹:递归调用微任务会导致主线程阻塞
2. 长任务分解技巧:用宏任务拆分耗时操作
3. 动画渲染优化:在requestAnimationFrame中更新DOM
4. 网络请求陷阱:fetch回调属于宏任务
5. Web Worker使用场景:超过50ms的任务建议移出主线程
6. async/await本质:语法糖包装的Promise链

五、性能优化实战案例

5.1 点击按钮的优化策略

“`javascript
// 错误写法:同步操作阻塞微任务
button.addEventListener(‘click’, () => {
heavyCalculation(); // 同步耗时操作
updateDOM(); // 需要等待重绘
});

// 正确写法:
button.addEventListener(‘click’, () => {
Promise.resolve().then(heavyCalculation).then(updateDOM);
});
“`

5.2 滚动事件节流方案

“`javascript
let isScrolling;
window.addEventListener(‘scroll’, () => {
// 清除未执行的宏任务
clearTimeout(isScrolling);

// 将操作放入宏任务队列
isScrolling = setTimeout(() => {
calculatePosition();
}, 100);
});
“`

总结:掌握调度规律,写出高性能代码

理解”同步→微任务→渲染→宏任务”这个黄金链条,就能精准控制代码执行时机。记住这三个核心要点:
1. 任何同步代码都不可中断
2. 微任务队列必须完全清空
3. 不同类型的宏任务有优先级差异

下次遇到异步代码调试时,不妨在关键节点插入console.log,亲自验证事件循环的运行规律。只有将理论转化为实践认知,才能真正驾驭JavaScript的异步世界。

正文完
 0

辉哥

一言一句话
-「
最新文章
怎样把淘宝店铺转让给别人?步骤清楚吗?

怎样把淘宝店铺转让给别人?步骤清楚吗?

怎样把淘宝店铺转让给别人?完整步骤详解(2025-2026最新指南) 在淘宝电商竞争日益激烈的今天,很多店主因...
淘宝店铺正规交易怎么做?用什么交易软件好?

淘宝店铺正规交易怎么做?用什么交易软件好?

淘宝店铺正规交易怎么做?用什么交易软件好? 在电商时代,淘宝店铺已成为许多人创业或变现的重要资产。有的创业者想...
淘宝店铺转让需要过户吗?完整流程是什么?

淘宝店铺转让需要过户吗?完整流程是什么?

淘宝店铺转让需要过户吗?完整流程是什么? 随着电商行业的快速发展,越来越多的商家选择在淘宝平台开店创业。但经营...
淘宝实名店铺能买吗?购买流程安全吗?

淘宝实名店铺能买吗?购买流程安全吗?

淘宝实名店铺能买吗?购买流程安全吗?一文读懂实名认证店铺购物指南 在淘宝购物时,很多消费者都会关注店铺的真实性...
淘宝四钻店铺值多少钱?转让行情如何?

淘宝四钻店铺值多少钱?转让行情如何?

淘宝四钻店铺值多少钱?转让行情如何? 淘宝作为中国最大的电商平台,吸引了无数创业者和商家入驻。在激烈的市场竞争...
淘宝同店宝贝转让会影响权重吗?

淘宝同店宝贝转让会影响权重吗?

淘宝同店宝贝转让会影响权重吗? 在淘宝开店的过程中,很多卖家会遇到宝贝转让的情况,尤其是同一家店铺内调整宝贝链...
淘宝童装店铺可以转让吗?童装生意好做吗?

淘宝童装店铺可以转让吗?童装生意好做吗?

淘宝童装店铺可以转让吗?童装生意好做吗?一文讲透转让流程与市场机会 在淘宝电商平台上,童装一直是热门品类之一。...
淘宝五钻店铺转让价格多少?行情如何?

淘宝五钻店铺转让价格多少?行情如何?

淘宝五钻店铺转让价格多少?2026年最新行情解析 在电商竞争日趋激烈的今天,许多创业者不再选择从零开始开淘宝店...
淘宝星级店铺能转让吗?星级代表什么意思?

淘宝星级店铺能转让吗?星级代表什么意思?

淘宝星级店铺能转让吗?星级代表什么意思? 在淘宝开店的创业者越来越多,很多新手都想快速起步,避免从零开始的漫长...
淘宝虚拟店铺可以出售吗?会不会违法?

淘宝虚拟店铺可以出售吗?会不会违法?

淘宝虚拟店铺可以出售吗?会不会违法?2026最新解答 在淘宝电商生态中,越来越多的卖家选择经营虚拟店铺,因为它...
淘宝一钻店铺出售值钱吗?价格怎么算?

淘宝一钻店铺出售值钱吗?价格怎么算?

淘宝一钻店铺出售值钱吗?价格怎么算? 在淘宝电商平台上,许多新手卖家和创业者都把“一钻”视为重要的里程碑。它代...