最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
JavaScript 事件循环机制如何运作
时间:2026-07-11 11:24:03 编辑:袖梨 来源:一聚教程网
JavaScript事件循环严格按节奏分步推进:先执行同步代码,再清空所有微任务,然后执行一个宏任务,如此循环;微任务(如Promise.then)优先级高于宏任务(如setTimeout),即使setTimeout(…,0)写在前面也后执行。
JavaScript 事件循环不是“等所有异步做完再执行”,而是严格按节奏分步推进:先跑完当前同步代码,再清空所有微任务,接着执行一个宏任务,如此往复。
宏任务和微任务怎么区分
宏任务是“大块工作”,比如整个 script 脚本、setTimeout/setInterval 回调、I/O 完成通知、UI 渲染、DOM 事件处理。它们排在宏任务队列里,每次只取一个执行。
微任务是“紧急插队的小活”,比如 Promise.then/catch/finally、queueMicrotask()、MutationObserver 回调。只要同步代码一结束,引擎立刻回头把当前所有微任务全部执行完,一个不留。
关键区别在于优先级:微任务永远比宏任务快一步。哪怕 setTimeout(…, 0) 写在 Promise.then 前面,输出顺序也一定是 Promise 先、setTimeout 后。
立即学习“Java免费学习笔记(深入)”;
事件循环每一轮具体做什么
- 执行当前宏任务中的全部同步代码(比如 console.log、函数调用、变量赋值)
- 遇到 setTimeout → 放入宏任务队列;遇到 Promise.then → 放入微任务队列
- 同步代码执行完毕,调用栈清空 → 立刻检查微任务队列
- 依次执行所有已排队的微任务(包括过程中新产生的微任务)
- 微任务队列清空后,浏览器可能触发一次 UI 渲染(如重绘)
- 从宏任务队列头部取出下一个任务,开始新一轮循环
async/await 实际怎么参与调度
async 函数本身是宏任务入口,但 await 后面的表达式一旦返回 Promise,就会把后续代码包装成微任务。
例如:
async function fn() {
console.log('1');
await Promise.resolve();
console.log('2');
}
fn();
console.log('3');
输出顺序是 1 → 3 → 2。因为 await 把 console.log('2') 推进了微任务队列,而 console.log('3') 是同步代码,紧接在 fn() 调用后执行。
常见误区提醒
- setTimeout(..., 0) 不代表“立刻执行”,只是尽快安排进宏任务队列,至少要等当前同步代码 + 所有微任务走完
- Promise.then 不是“马上运行”,它注册的是微任务,必须等本轮同步结束才触发
- fetch() 返回 Promise,但 .then 或 await 才决定回调何时加入微任务队列,不是请求发出那一刻就排队
- 多个 Promise.then 链式调用,每个 .then 都生成新微任务,会按注册顺序依次执行
相关文章
- 电脑自带画图工具调整图片尺寸 07-11
- UC浏览器关闭Direct Write方法 07-11
- Python write写入空白问题解决 07-11
- 表单设计器填报预览展示方法 07-11
- 异环是哪家公司开发的 手游异环开发商背景与制作团队揭秘 07-11
- JavaScript输出1到100 07-11