事件循环核心是“谁在什么时候、怎么把任务送进主线程”,分四部分:调用栈执行同步任务(lifo);宏任务队列含settimeout等;微任务队列含promise.then等;环境模块负责推回调。每轮先执行一个宏任务,再清空全部微任务,然后渲染,再取下一宏任务。

事件循环(Event Loop)是 JavaScript 运行机制的底层心脏,画思维导图时不必堆砌术语,重点落在“谁在什么时候、怎么把任务送进主线程”这个主线上。核心不是记住名词,而是理清同步/异步、调用栈/队列、宏任务/微任务之间的协作关系。
主线程与调用栈:同步任务的执行现场
所有直接写的代码(比如函数调用、变量赋值、for循环)都属于同步任务,它们会立即压入调用栈,逐行执行,栈空了才轮到别的任务。
- 调用栈是后进先出(LIFO),函数执行完就弹出
- 报错信息里的 “at xxx” 就是调用栈快照
- 无限递归会导致栈溢出(RangeError)
任务队列分两类:宏任务和微任务
异步操作不会卡住主线程,而是交给浏览器或 Node.js 的对应模块(如定时器、网络请求)处理;完成后,回调函数被放入不同优先级的队列:
- 宏任务队列:setTimeout、setInterval、I/O、UI渲染、script标签整体代码
- 微任务队列:Promise.then/catch/finally、queueMicrotask、MutationObserver回调
- 每次宏任务执行完,必须清空当前全部微任务,再取下一个宏任务
事件循环运转三步走
这是一个持续不断的循环,不依赖开发者手动触发:
- 执行一个宏任务(比如全局脚本或某个定时器回调)
- 执行过程中遇到 Promise.then,就把它加入微任务队列;遇到 setTimeout,就注册进宏任务队列
- 宏任务结束 → 立即执行所有排队中的微任务 → 浏览器可能渲染一次 → 取下一个宏任务
画导图时建议聚焦这四个节点
用中心辐射式布局,把“Event Loop”放在正中,向外延伸四条主干:
- 调用栈(标注:同步、LIFO、阻塞)
- 宏任务队列(举例:setTimeout、setInterval、I/O)
- 微任务队列(举例:Promise.then、queueMicrotask)
- 浏览器/Node环境模块(标注:负责监听事件、计时、网络,只负责“推回调”,不执行)











