什么是JavaScript事件循环_宏任务与微任务谁先执行?

狼影

狼影

2026-01-04

679人浏览

原创

微任务在当前宏任务结束后、下一个宏任务开始前立即清空执行,故promise.then总比settimeout先运行;宏任务典型有settimeout、i/o、ui渲染等,微任务典型有promise.then、queuemicrotask、mutationobserver、process.nexttick(node.js特有,优先级最高)。

什么是javascript事件循环_宏任务与微任务谁先执行?

微任务在当前宏任务结束后、下一个宏任务开始前立即执行,所以 Promise.then 总是比 setTimeout 先运行。

宏任务和微任务的典型代表有哪些?

区分二者的关键不是“谁更小”,而是浏览器/Node.js引擎定义的**任务分类规则**:

  • 宏任务(Macrotask):setTimeoutsetIntervalsetImmediate(Node.js)、I/O 回调、UI 渲染(浏览器)、postMessage
  • 微任务(Microtask):Promise.then/catch/finallyqueueMicrotaskMutationObserver 回调、process.nextTick(Node.js,优先级高于 Promise)

注意:process.nextTick 是 Node.js 特有,它不属于标准微任务队列,但执行时机比 Promise 更早——它会在当前操作完成后、任何微任务之前执行。

事件循环中它们的执行顺序到底是怎样的?

一次完整的事件循环流程是:

度加AI
度加AI

度加AI官网入口,百度官方 AIGC 创作平台,支持 AI 成片、AI 生文、数字人、声音克隆、配音字幕与智能剪辑等在线创作能力。

下载
  1. 执行一个宏任务(比如主线程脚本、或某个 setTimeout 回调)
  2. 执行过程中遇到 Promise,其 then 被推入微任务队列;遇到 setTimeout,其回调被推入宏任务队列
  3. 当前宏任务执行完,**立刻清空整个微任务队列**(所有已排队的微任务依次执行,且新加入的微任务也会在这轮被处理)
  4. 然后才从宏任务队列取下一个任务(可能是渲染、也可能是另一个 setTimeout

这意味着:哪怕你在微任务里又创建了新的微任务,它也会被本轮执行掉,不会等到下一轮宏任务之后。

console.log(1);
setTimeout(() => console.log(2), 0);
Promise.resolve().then(() => console.log(3));
Promise.resolve().then(() => console.log(4));
console.log(5);
// 输出:1 → 5 → 3 → 4 → 2

为什么 async/await 看起来像同步,实际还是微任务?

async 函数返回的是 Promiseawait 后面的表达式一旦 resolve,后续代码会被包装进 Promise.then —— 所以它本质仍是微任务调度。

  • await 不会阻塞线程,只是让出控制权,等 Promise settled 后再把后续逻辑排进微任务队列
  • 多个 await 链式调用,每一步 resolve 后都会触发一次微任务排队
  • 如果 await 的是普通值(非 Promise),V8 会自动包装成 Promise.resolve(value),仍走微任务流程
console.log('start');
async function foo() {
  console.log('before await');
  await Promise.resolve();
  console.log('after await');
}
foo();
console.log('end');
// 输出:start → before await → end → after await

真正容易被忽略的是:微任务队列在每次宏任务后被**完全清空**,而不是只执行一个。这个“清空”行为会让嵌套的 Promise.then 或连续的 queueMicrotask 表现出极强的连续性,甚至可能引发栈溢出风险(比如递归调用 queueMicrotask 却不设退出条件)。

Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南

相关专题

更多
堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

2023.07.18

2195

5

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

2023.08.10

1146

6

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

2023.08.10

2039

6

js正则表达式
js正则表达式

php中文网为大家提供各种js正则表达式语法大全以及各种js正则表达式使用的方法,还有更多js正则表达式的相关文章、相关下载、相关课程,供大家免费下载体验。

2023.06.20

1806

8

js获取当前时间
js获取当前时间

JS全称JavaScript,是一种具有函数优先的轻量级,解释型或即时编译型的编程语言;它是一种属于网络的高级脚本语言,主要用于Web,常用来为网页添加各式各样的动态功能。js怎么获取当前时间呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.07.28

888

5

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.03

1150

5

js是什么意思
js是什么意思

JS是JavaScript的缩写,它是一种广泛应用于网页开发的脚本语言。JavaScript是一种解释性的、基于对象和事件驱动的编程语言,通常用于为网页增加交互性和动态性。它可以在网页上实现复杂的功能和效果,如表单验证、页面元素操作、动画效果、数据交互等。

2023.08.17

7861

11

js删除节点的方法
js删除节点的方法

js删除节点的方法有:1、removeChild()方法,用于从父节点中移除指定的子节点,它需要两个参数,第一个参数是要删除的子节点,第二个参数是父节点;2、parentNode.removeChild()方法,可以直接通过父节点调用来删除子节点;3、remove()方法,可以直接删除节点,而无需指定父节点;4、innerHTML属性,用于删除节点的内容。

2023.09.01

637

4

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

2023.09.04

1187

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
WebStorm 官方调试文档
WebStorm 官方调试文档

共0课时 | 0人学习

React 教程
React 教程

共58课时 | 11.1万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 6.1万人学习