事件循环实践
258 The Event Loop in Practice
一、视频基础信息
- 所属课程:Udemy 排名第一的 JavaScript 课程《2023 最新完整 JavaScript 课程 从入门到精通 – 通过项目、挑战和理论掌握 JS》(中英文字幕版·下)
- 视频定位:该课程第 42 集,聚焦 JavaScript 事件循环(Event Loop)的实践应用,是异步 JavaScript 学习的核心实操内容
- 课程规模:课程合集共 98 集,本集是理解事件循环机制从理论到实践的关键过渡内容
二、核心知识:事件循环实践核心示例
2.1 示例代码构建
视频通过编写以下核心代码,引出事件循环执行顺序的思考,代码逻辑拆解如下:
1 | // 1. 同步代码:第一次打印“测试” |
2.2 关键问题提出
基于上述代码,视频引导观众思考:4 条打印语句在控制台的输出顺序是什么?
(建议先暂停视频独立分析,再对照后续逻辑验证)
三、核心逻辑:事件循环执行顺序分析
3.1 第一步:明确任务类型分类
事件循环中,JavaScript 任务分为两类,优先级差异是执行顺序的核心决定因素:
| 任务类型 | 定义 | 本示例中的对应任务 |
|---|---|---|
| 同步任务 | 主线程直接执行,无需进入任务队列的代码 | 两次 console.log("测试") |
| 微任务(Microtask) | 优先级高于宏任务,同步任务执行完后立即执行,需进入“微任务队列” | Promise.then() 回调 |
| 宏任务(Macrotask) | 优先级低于微任务,微任务队列清空后才执行,需进入“宏任务队列” | setTimeout 回调(即使延迟 0ms) |
3.2 第二步:执行顺序推导(含例题验证)
例题 1:基于上述代码,推导输出顺序
-
第一步:执行同步任务
主线程优先执行所有同步代码,因此先输出:1
2测试1
测试2 -
第二步:清空微任务队列
同步任务执行完毕后,主线程会先检查微任务队列。本示例中,Promise.resolve()立即 resolved,其then回调已进入微任务队列,因此执行微任务,输出:1
Promise 成功结果
-
第三步:执行宏任务队列
微任务队列清空后,主线程才检查宏任务队列。setTimeout(..., 0)的回调虽设置延迟 0ms,但仍属于宏任务,此时才执行,输出:1
零秒计时器回调
-
最终输出顺序结论:
测试1 → 测试2 → Promise 成功结果 → 零秒计时器回调
四、拓展实验:微任务耗时对宏任务的影响
4.1 实验代码构建
为验证“微任务优先级高于宏任务”的实际影响,视频新增含耗时操作的微任务,代码如下:
1 | console.log("测试1"); |
4.2 实验现象与结论
例题 2:分析上述代码的执行现象
- 现象:运行代码后,“零秒计时器回调”会明显延迟输出,需等待微任务中的 1 亿次循环执行完毕后才出现
- 结论:
- JavaScript 计时器(如
setTimeout)无法保证“精确延迟执行”,其回调的执行依赖宏任务队列的调度 - 若微任务执行耗时较长,会阻塞后续宏任务的执行,导致宏任务“延迟触发”,进一步印证“微任务队列优先级高于宏任务队列”的核心规则
- JavaScript 计时器(如
五、视频总结与后续预告
5.1 核心知识点总结
- 事件循环执行流程:同步任务 → 清空微任务队列 → 执行宏任务队列(循环)
- 任务优先级:同步任务 > 微任务(如 Promise.then)> 宏任务(如 setTimeout)
- 关键注意点:
setTimeout(..., 0)仅表示“尽快执行”,不代表“零秒后立即执行”,需受微任务执行情况影响
5.2 后续内容预告
下一节视频将回归异步 JavaScript 实践,从基础开始讲解“如何手动创建 Promise”,进一步深入 Promise 的底层逻辑与应用场景。
本文是原创文章,采用CC BY-NC-SA 4.0协议,完整转载请注明来自木鱼的鱼窝


