先看三行代码,猜猜输出顺序:
console.log('Hi');
setTimeout(() => console.log('there'), 0);
console.log('JSConfEU');
延迟是0毫秒,there是不是紧跟着Hi出来?很多人凭直觉会这么答——然后当场翻车。正确顺序是Hi、JSConfEU、there。为什么一段“零延迟”的代码会排在所有同步代码之后?这个问题背后藏着的,就是JavaScript世界最核心也最被误解的机制:事件循环(Event Loop)。
今天要深读的,就是把这个问题讲透的传奇讲座——《What the heck is the event loop anyway?》。这是Philip Roberts在JSConf EU 2014上的26分钟演讲,十多年过去,它仍是学习JavaScript异步机制公认的第一入口:几乎所有讲事件循环的文章,追根溯源都会引到它。更妙的是,它不堆术语,而是现场用可视化工具把“看不见的调度过程”演给你看。
在2026年读它一点不过时:AI写的异步代码满天飞,await到处都是,但当代码卡死、时序错乱时,能说清“到底谁在等谁”的工程师依然稀缺。这26分钟,补的正是那块最底层、最值钱的拼图。
| 项目 | 内容 |
|---|---|
| 视频标题 | What the heck is the event loop anyway?(到底什么是事件循环?) |
| 频道 | JSConf(JSConf EU 2014官方录像) |
| 时长 | 约26分钟 |
| 播放量 | 百万级(长期居JS原理讲解类视频热度前列,实时数据以页面为准) |
| 核心主题 | 用现场演示讲透JavaScript的单线程模型、调用栈与事件循环 |
【视频内容】Philip Roberts的开场非常坦诚:他说自己在准备这次演讲前,专门去问了身边的朋友“事件循环到底是怎么工作的”,得到的回答基本都是“呃……大概是那么回事吧”。这个现象本身比答案更有意思——JavaScript开发者天天在写异步代码,回调、setTimeout、AJAX张口就来,但问起“浏览器内部是怎么安排这些事儿的”,绝大多数人答不上来。他把原因归结为:这个机制明明是JavaScript并发的核心,却在各种教程里被一句“异步非阻塞”轻轻带过。
【延伸分析】这个“集体说不清”的状态到今天也没根本好转,只是症状变了:以前大家背不清回调时序,现在大家搞不清await之后代码到底跑到哪个队列里去了。工具越自动,原理越欠账——这正是这门老课反复被翻出来重看的原因。
【视频内容】讲座的第一个关键动作是“拆东西”。他先画出了V8引擎的组成:调用栈(call stack)和堆(heap)——堆管内存分配,栈管“函数调用到哪一步了”。然后他抛出全场最重要的一个澄清:V8里根本没有setTimeout!定时器、DOM事件、AJAX这些我们以为属于"JavaScript"的能力,其实是浏览器提供的Web APIs,它们活在JavaScript运行时之外。换句话说:JS运行时确实是单线程的,但浏览器本身是个多面手,它能同时盯着计时器、监听点击、等网络响应。
【延伸分析】这一层澄清是理解一切异步怪象的钥匙。后来Node.js的出现完美印证了这个模型:Node换掉了Web APIs这一层,改由C++编写的libuv提供等价能力,但“单线程JS + 宿主环境代劳异步”的骨架一模一样。学会这一层,你等于同时理解了浏览器和服务器两套JS。
【视频内容】重头戏来了。Philip说,事件循环本身简单得令人发笑——它就是一小段代码,唯一的工作是循环检查:调用栈空了吗?空了,且回调队列里有东西,就把队首的回调推上调用栈执行。如此往复。没有更复杂的魔法。他在现场用一个动图反复演示完整流程:同步代码在栈上执行完毕、栈变空;事件循环“看一眼”队列;把队首回调推进栈;执行完再看下一轮。setTimeout(fn, 0)之所以不会“立即”执行,就是因为不管延迟多短,回调都得先在队列里排队,等当前这轮同步代码全部跑完、栈彻底空了,才轮得到它。
【延伸分析】“栈空才派活”这五个字,值得背下来。它解释了为什么Promise.then和setTimeout同时存在时前者总先跑(前者进的是微任务队列,后者是宏任务队列——这是2014年那版讲解尚未覆盖的续集,下文会展开),也解释了为什么Vue、React的某些“怪异更新时序”本质都是同一件事:同步代码没跑完之前,排队的永远插不上手。
【视频内容】讲了原理,他立刻“作案”:现场跑一段超长的同步循环,让调用栈被一个慢任务死死占住。结果整张网页瞬间冻结——按钮点不动、动画停摆、输入没反应。原因正是刚才那条规则:渲染也是排队的一份子,调用栈不空,浏览器连画一帧画的机会都没有。他借此说明:JavaScript选单线程不是偷懒,而是刻意的取舍——一根栈意味着没有死锁、没有线程竞态,写代码的心智模型简单到极致;代价就是“占着栈的慢代码会拖垮一切”。
【延伸分析】这个冻结演示放到今天更有代入感:现代性能指标INP(Interaction to Next Paint)衡量交互响应,长任务(Long Task)的判定线定在50毫秒——本质上就是这段演示的工程化版本:任何占用主线程超过50毫秒的任务,都在重演他现场那场“页面冻结”。十二年前的一次demo,如今变成了搜索引擎排名的考核项。
【视频内容】他接着把“慢”拆成两种。同步的慢是灾难:代码占着调用栈,什么都干不了,页面跟着陪葬。异步的慢则无害:把慢操作(比如网络请求)交给Web APIs,回调进队列排队,调用栈始终空闲,页面照常响应,慢的只是“那个回调晚点执行”。所以他给出的结论朴素而有力:在单线程的JS世界里,慢代码本身不是罪,占着主线程的慢代码才是。写代码的目标不是消灭慢,而是不让慢占道。
【延伸分析】“把慢事委托出去”是整个前端工程乃至Node后端工程的元规则。Node社区为什么对fs.readFileSync这类同步API深恶痛绝?因为在服务器上,一个同步调用冻住的不是你一个人的页面,是所有并发用户的请求。同一条原理,两端通用。
【视频内容】这场讲座还有一个隐藏彩蛋:为了把不可见的调度过程演出来,Philip Roberts专门写了一个可视化工具Loupe——网页里直接跑一段JS代码,右侧同步动画展示“调用栈、Web APIs、回调队列”三方的实时流转。讲座里的所有演示都是在Loupe里跑的,观众能亲眼看到setTimeout的回调如何“飞出”调用栈、进入Web API区倒数、再到队列里排队、最后被事件循环送回栈上。
【延伸分析】这是我认为这场讲座比绝大多数文字教程高明的地方:它给的不是结论,是一台可以自己动手的显微镜。教育心理学里讲“可视化外部表征”能大幅降低工作记忆负担,Loupe就是教科书级的应用。任何觉得异步难的人,差的往往不是智商,而是这样一台显微镜。
【延伸分析】必须坦白:这场讲座有个“时代局限”——它讲的队列只有一条,而现代JS规范里其实有两条:宏任务队列(macrotask)和微任务队列(microtask)。Promise.then、async/await的后续走的是微任务,规则是“每跑完一个宏任务,微任务队列必须整个清空,才轮到下一个宏任务”。这套机制是2015年ES6随Promise规范化后才定型的,讲座里自然没讲。但恰恰因为如此,这场课才是正确的学习起点:先把“单线程+队列+栈空派活”的最简模型建立起来,再叠加微任务规则,认知就不会乱。反过来,一上来就背“宏微任务七条时序口诀”的人,多半背成了浆糊。此外,AI辅助编码时代有个新真相:AI能写出正确的异步代码,但时序bug的现场诊断永远落在人身上——没有运行时模型的人,连问题描述都写不清楚。
flowchart TD
A["调用栈:一次只干一件事"] -->|慢任务占住栈| B["渲染冻结:页面卡死"]
B -->|解法:把慢活交出去| C["Web APIs 代劳"]
C -->|完成后回调排队| D["回调队列"]
E["事件循环"] -->|栈空才取队首| A
D --> E
F["setTimeout 到点"] --> D
G["DOM 事件触发"] --> D
H["AJAX 响应到达"] --> D
写代码时,记住一条军令:主线程上不做慢活。超过50毫秒的任务考虑拆分——把大循环切成小块,每块之间用await或调度API(如requestIdleCallback、新一代的scheduler.yield())让出主线程,给渲染和交互喘息的机会;纯计算型重活(大文件解析、图像处理)交给Web Worker,它有真正独立的线程,通过postMessage通信,不占主线程一根毛。
排查卡顿时,你现在有了模型:页面冻死=调用栈被占,先查长任务。打开Chrome DevTools的Performance面板录一段,红色长条就是“占道的慢代码”,定位它、拆掉它,卡顿自然消失。
学Node.js时,警惕一切名字里带Sync的API。服务器上的同步IO等于替所有用户按下了暂停键,这是很多新手把本地脚本顺利、上线就雪崩的根源。
学习方法上,强烈建议用Loupe亲手跑三段代码:一段纯同步、一段setTimeout(fn, 0)、一段定时器加点击事件混合——十分钟的实际观察胜过十篇背时序口诀的文章。然后再去补微任务(Promise、await)的进阶规则,由简入繁,事半功倍。
JavaScript从来不是异步的语言——异步是宿主环境替它排的队,而事件循环只是那个“栈空就派活”的守门人;看懂这26分钟,你看懂的不只是setTimeout,而是整个前端的性能问题从哪来、该往哪去。
本文由「51学通信」技术团队出品。51学通信由通信行业18年老兵爱卫生(微信ID: gprshome201101)维护,聚焦5G/6G核心网、3GPP标准解读、通信前沿技术深度分析。 出版作品有《5G核心网原理与实践》《IMS原理与实践》等4本通信专业书籍。知识星球「51学通信」提供深度技术答疑和行业洞察。
[!tip] 51学通信知识星球 星主:爱卫生(微信:gprshome201101)——公众号「51学通信」创办者,19 年通信行业运维与讲师经验,著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书(各大电商平台有售)。 星球定位:深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域,主打运维岗位与信令分析。 当前规模:5200 篇主题 / 990 个回答,198 元/年。 加入福利:加入星球后请加爱卫生微信,拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题,另有群内分享。 AI 加持:51学通信知识星球已作为 skill 接入 WorkBuddy,使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例,做总结、找文档和 PPT 等场景全覆盖。
