本文是个人阅读推荐,非原创。原文作者:腾讯云开发者社区

为什么推荐这篇文章

学 Promise、学 async/await、学事件循环——我相信大部分前端都经历过这个过程:看了无数教程,能背出"链式调用"“解决回调地狱"这些概念,但一碰到执行顺序的题目就懵。

问题出在哪?我们跳过了底层机制,直接去学上层 API。

这篇文章做了一件很多人没做过的事:从浏览器是多进程的这个事实出发,一路梳理到 JS 引擎的单线程本质,再到 Event Loop 的完整机制。 读完之后你会发现,Promise 的所有行为都变得合理且可预测,而不是需要死记硬背的"规则”。

文章讲了什么

大致脉络:

  1. 进程 vs 线程 —— 用工厂和工人的比喻讲清楚区别,不啰嗦
  2. 浏览器是多进程的 —— 每个 Tab 页是一个独立进程,Browser 进程、GPU 进程、渲染进程各司其职
  3. 浏览器内核(渲染进程)内部的线程关系 —— GUI 渲染线程与 JS 引擎线程互斥,这就是为什么 JS 会阻塞页面渲染
  4. JS 引擎的单线程本质 —— JS 引擎线程一次只能做一件事,但浏览器其他线程可以并行
  5. Event Loop 完整机制 —— 宏任务、微任务、任务队列,讲得非常透彻
  6. 定时器的真相 —— setTimeout 不是精确计时,而是交给浏览器定时器线程处理

最值得读的部分

我个人觉得最有价值的三个点:

① JS 引擎线程和 GUI 渲染线程互斥

这解释了为什么耗时的 JS 代码会导致页面卡顿——不是因为 JS “慢”,而是因为它们抢同一个线程,JS 执行时页面没法渲染。

② 异步的本质是"外包"

JS 遇到 setTimeout、网络请求等异步操作时,自己不会去做,而是交给浏览器的其他线程(定时器线程、网络线程等),完成后把回调函数放回任务队列,等主线程空闲时再执行。这就是发布订阅模式的实际应用。

③ 微任务优先级高于宏任务

每次执行完一个宏任务后,会先清空所有微任务(Promise.then 的回调),再去取下一个宏任务(setTimeout 的回调)。这一个规则就能解释 95% 的执行顺序问题。

适合谁读

  • 用过 Promise 但说不清执行顺序的前端开发者
  • 想真正理解 async/await 为什么"看起来像同步"的人
  • 面试被事件循环题虐过的朋友
  • 任何想从"会用"进阶到"理解"的前端

⚠️ 原文较长,适合有一定基础的开发者。新手可以分批阅读,先理解进程/线程的概念,再看 Event Loop 部分。

原文链接

👉 从浏览器多进程到JS单线程,JS运行机制最全面的一次梳理


推荐给和我一样曾经在异步编程中迷茫过的朋友。先把底层搞懂,上层的 API 自然就通了。