首页 > web前端 > js教程 > 正文

JS事件循环机制解析_宏任务与微任务指南

betcha
发布: 2025-11-16 13:12:06
原创
345人浏览过
事件循环先执行宏任务,再清空微任务队列。同步代码如console.log立即执行,setTimeout等宏任务进入宏任务队列,Promise.then等微任务进入微任务队列。当前宏任务结束后,依次执行所有微任务,之后再取下一个宏任务。async/await基于Promise,await后续代码被视为微任务。例如:script start→async1 start→async2→script end→async1 end→timeout,因await将“async1 end”推入微任务队列,在本轮宏任务结束后执行。

js事件循环机制解析_宏任务与微任务指南

JavaScript 的事件循环机制是理解异步编程的关键。很多人在处理 setTimeoutPromiseasync/await 时会感到困惑,原因就在于没有搞清楚宏任务(Macrotask)和微任务(Microtask)的执行顺序。下面我们就来清晰地梳理这套机制。

事件循环基础:什么是宏任务与微任务?

JavaScript 是单线程语言,所有代码都在一个主线程上执行。为了实现异步操作而不阻塞主线程,JS 引入了事件循环机制。这个机制依赖两个任务队列:

  • 宏任务队列(Macrotask Queue):也叫任务队列,用于存放宏任务。常见的宏任务包括:setTimeoutsetIntervalI/O 操作UI 渲染script 标签中的整体代码
  • 微任务队列(Microtask Queue):优先级高于宏任务。常见的微任务包括:Promise.then/catch/finallyqueueMicrotaskMutationObserver浏览器环境)。

每次事件循环开始时,先执行当前宏任务中的同步代码,然后清空微任务队列,再取下一个宏任务执行,如此反复。

执行顺序规则:宏任务与微任务如何调度?

事件循环遵循以下流程:

  • 从宏任务队列中取出一个任务执行(比如 script 主代码块或 setTimeout 回调)。
  • 执行过程中遇到同步代码,直接运行。
  • 遇到微任务(如 Promise.then),将其加入微任务队列。
  • 当前宏任务执行完毕后,立即清空微任务队列中所有任务,按先进先出顺序执行。
  • 微任务清空后,进入下一轮事件循环,取下一个宏任务执行。

关键点是:每完成一个宏任务,就会把所有当前可用的微任务执行完。

实际例子:看懂输出顺序

来看一段经典代码:

console.log('start');

setTimeout(() => {
  console.log('timeout');
}, 0);

Promise.resolve().then(() => {
  console.log('promise');
});

console.log('end');
登录后复制

输出结果为:

腾讯小微
腾讯小微

基于微信AI智能对话系统打造的智能语音助手解决方案

腾讯小微 26
查看详情 腾讯小微
start
end
promise
timeout
登录后复制

解释:

  • “start” 是同步代码,最先输出。
  • setTimeout 是宏任务,被放入宏任务队列。
  • Promise.then 是微任务,进入微任务队列。
  • “end” 是同步代码,紧接着输出。
  • 当前宏任务(主 script)执行完,开始执行微任务,输出 “promise”。
  • 微任务清空后,进入下一轮事件循环,执行 setTimeout 回调,输出 “timeout”。

async/await 与微任务的关系

async 函数返回一个 Promise,而 await 后面的表达式完成后,其后续代码会被当作微任务处理。

async function async1() {
  console.log('async1 start');
  await async2();
  console.log('async1 end');
}

async function async2() {
  console.log('async2');
}

console.log('script start');

setTimeout(() => {
  console.log('timeout');
}, 0);

async1();

console.log('script end');
登录后复制

输出为:

script start
async1 start
async2
script end
async1 end
timeout
登录后复制

注意 “async1 end” 在 “script end” 之后输出,是因为 await 相当于把后面的代码包装成 Promise.then,属于微任务。

基本上就这些。掌握宏任务和微任务的执行时机,就能准确预测异步代码的输出顺序。不复杂但容易忽略细节。

以上就是JS事件循环机制解析_宏任务与微任务指南的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号