事件循环的核心是理解代码执行顺序:单线程靠宿主环境实现非阻塞;微任务(如promise.then)总在宏任务(如settimeout)之前执行;async/await本质是promise微任务。

面试中问到事件循环,不是考你背概念,而是看你能不能说清“代码为什么这么执行”。核心就三点:单线程怎么不卡住、宏任务和微任务谁先跑、Promise 和 setTimeout 到底谁更“急”。
单线程 ≠ 只能干等
JavaScript 主线程只有一条,但浏览器或 Node.js 提供了额外的线程来处理耗时操作。比如发起网络请求、读文件、计时,这些实际工作由定时器线程、HTTP 线程等完成。主线程只负责注册回调、调度执行——等异步操作完成,再把对应的回调放进任务队列,等空闲时执行。
所以“非阻塞”不是 JS 自己变多线程了,是靠宿主环境配合实现的。
PHP中文网提供 Genspark AI 桌面客户端及浏览器的 Windows 官方获取入口与安装教程。作为强大的 AI 智能体搜索引擎与自动化平台,Genspark AI 完美适配 Windows 系统,支持本地文件处理与多模型协同。通过本页面,您可以快速下载并安装 Genspark AI,一键体验超级智能体(Super Agent)、异步代理(Autopilot Agent)以及一键生成 PP
执行顺序有严格优先级
一次事件循环周期里,顺序固定:
- 先执行所有同步代码(进调用栈,一气呵成)
- 同步代码结束,立刻清空当前轮次的微任务队列(Promise.then、async/await 后续、MutationObserver)
- 微任务全部执行完,才取一个宏任务(setTimeout、setInterval、script 整体、I/O 回调等)来执行
- 新宏任务执行中若产生微任务,它们会排进本轮微任务队列末尾,等当前宏任务结束再统一执行
常见陷阱题怎么破
很多题目看似绕,其实只在测你是否分得清宏微任务的插入时机和清空节奏:
- setTimeout(fn, 0) 不一定比 Promise.then 快:它进的是宏队列,而 Promise.then 进的是微队列;微任务永远插在当前宏任务之后、下一个宏任务之前
- 多个 then 链式调用是串行微任务:每个 then 返回的新 Promise 的回调,都会作为下一个微任务入队,不会跳过当前轮次
- async/await 是 Promise 语法糖:await 后面的表达式一旦 resolve,后续代码会被包装成微任务,不是立即执行
不复杂但容易忽略










