A1. 要素 (核心零件)

  1. Call Stack (调用栈): 主跑道。所有的 JS 代码(函数)都在这里执行。后进先出 (LIFO)。
  2. Web APIs (浏览器能力/Node.js的 API): 幕后工人。负责 setTimeout 计时、fetch 网络请求、DOM 事件监听。它们独立于 JS 主线程运行。
  3. Callback Queue (任务队列): 候车室。异步操作完成后的回调函数(如 onload、then)在这里排队。
    • 进阶区分: 宏任务 (MacroTask): 比如 setTimeout, setInterval, I/O。
    • 进阶区分: 微任务 (MicroTask): 比如 Promise.then, process.nextTick

A2. 结构 (运行规则) 这是一个无限循环:

  1. 执行栈: 先把 Stack 里所有的同步代码跑完。(html 当中的
  2. 执行宏任务: 先执行宏任务队列当中一个任务,并把下一个任务推入宏任务队列当中。
  3. 检查微任务: 执行完一个宏任务过后,立刻查看微任务队列(VIP 通道)。如果有,全部执行完。
  4. 渲染更新阶段:
    • 检查当前帧是否有渲染需求(如果未到刷新时间或页面完全无变化,则跳过此阶段)。
    • Resize/Scroll 事件:处理窗口缩放或滚动。
    • 执行 requestAnimationFrame (rAF): 这是开发动画的最佳时机,因为它能确保回调在计算样式和布局之前执行。
    • 样式计算 (Recalculate Style):确定每个元素应用哪些 CSS 规则。
    • 布局 (Layout/Reflow):计算每个元素在屏幕上的几何位置。
    • IntersectionObserver:处理元素可见性变化的回调。
    • 绘制 (Paint):构建图层树,提交给合成线程(Compositor Thread)进行栅格化和显示。
    • 分层与合成:浏览器将各个图层分别绘制过后,最后由GPU合成在一起
  5. 浏览器空闲阶段:如果当前帧在完成上述工作后还有剩余时间(小于 16.6ms),且无紧急任务,执行 requestIdleCallback回调
  6. 循环: 回到第 2 步。

A3. 系统 (涌现功能) 这个系统实现了**“非阻塞 I/O”**。JS 不会因为网络请求慢而卡死界面,它把耗时任务甩给浏览器(Web APIs),自己继续处理用户的点击,等数据回来了再处理数据。

如果切到 Node 语境,可以继续看 Node 包含哪些线程:Node 默认通常是一个进程,由 JS 主线程、底层线程池和宿主能力一起支撑事件循环。

console.log('1. 开始');
 
setTimeout(() => {
    console.log('2. 宏任务 (普通排队)');
}, 0);
 
Promise.resolve().then(() => {
    console.log('3. 微任务 (VIP插队)');
});
 
console.log('4. 结束');

输出顺序: 1 → 4 → 3 → 2 (注意:3 竟然在 2 前面,尽管 2 是先写的)