JS事件循环:别被那些所谓的“异步”术语给忽悠了

在北京极客 中级 2026/7/26 69 浏览 8 点赞 约 2 分钟

很多人把 JavaScript 吹成单线程、非阻塞、异步并发,听起来很高大上,但如果你真去问 V8 引擎,它可能会告诉你它只认得调用栈(Call Stack)和内存堆(Memory Heap),至于什么事件循环、回调队列,它压根不关心。

这就是最反直觉的地方:让 JS 具备异步能力的“事件循环”,根本就不是 JS 语言本身的一部分,而是由运行环境(浏览器或 Node.js)提供的。

想搞清楚为什么 setTimeout(fn, 0) 竟然不会立即执行,或者为什么 Promise 总是抢在定时器前面运行,得先认清这个底层逻辑:

单线程 = 只有一个调用栈 = 一次只能干一件事。

JS事件循环:别被那些所谓的“异步”术语给忽悠了

如果 JS 真的在等待一个 API 请求返回,整个页面就直接卡死了。为了解决这个问题,运行环境(比如浏览器的 Web APIs 或 Node.js 的 libuv)接管了耗时操作。

所谓的事件循环,本质上就是一个没完没了的 while 循环,逻辑简单到离谱:

let eventLoopQueue = [];

while (true) { 
  // 每一个循环周期被称为一个 "Tick"
  if (eventLoopQueue.length > 0) {
    // 只要调用栈空了,就从队列里抓一个任务扔进去执行
    let nextTask = eventLoopQueue.shift(); 
    nextTask(); 
  }
}
JS事件循环:别被那些所谓的“异步”术语给忽悠了

这个机制把 JS 变成了个“调度员”。当你调用 setTimeout 时,JS 并不是在计时,而是告诉浏览器:“帮我计时 1 秒,时间到了把这个回调函数扔进队列里。”

这时候 JS 继续执行后面的代码,直到调用栈清空,事件循环才会把那个回调函数从队列里拉回来执行。

这里有个关键的实战细节:不同环境的异步实现完全不同。

  • 浏览器端: 由浏览器内核提供 Web APIs(如 fetch, setTimeout)。
  • Node.js 端: 依赖 C++ 编写的 libuv 库来处理文件系统、网络等底层异步操作。
JS事件循环:别被那些所谓的“异步”术语给忽悠了
所以,别再把事件循环当成某种神秘的魔法,它就是一个在后台不停检查“栈是否为空”的死循环。
AI编程AI编程实战nodeprogrammingjavascript

全部回复 (4)

脚本小子小柯 专家 2026/7/26

把V8当成调度员,浏览器API才是真干活的苦力,这么想就通了!

0 回复
程序员Tom 高级 2026/7/26

微任务优先级这块儿要是被浏览器反手截胡,代码逻辑直接得崩掉吧?

0 回复
杭漂码农 专家 2026/7/26

@程序员Tom 别被面试题给绕进去了,直接拿 Node.js 跑一遍就通了。

0 回复
架构师老刘 中级 2026/7/26

死磕Promise执行顺序简直是浪费时间,直接翻浏览器源码才发现被坑了。

0 回复

发表回复

支持 Markdown 格式