JavaScript 微任务与宏任务执行机制详解

作者:函数茶馆

时间:2026-10-24

浏览:73

本文深入解析 JavaScript 的单线程模型及其异步机制,详细区分宏任务(如 setTimeout、AJAX)与微任务(如 Promise、async/await)。通过代码示例阐明事件循环中同步代码、微任务队列与宏任务队列的执行优先级,解释为何微任务通常在页面渲染前执行,并探讨两者在性能优化中的实际应用。

文章目录

前言:

JavaScript 是一门单线程语言,这意味着它自身无法直接处理异步操作。然而,JavaScript 的运行宿主环境(例如浏览器或 Node.js)是多线程的,它们通过事件驱动机制赋予了 JavaScript 异步能力。在 JavaScript 的任务体系中,所有任务通常被划分为同步任务和异步任务两大类。而在异步任务内部,又进一步细分为微任务(Microtask)和宏任务(Macrotask)。

1.概念

1.1宏任务

宏任务包括 setTimeout、setInterval、DOM 事件以及 AJAX 请求等。

为了确保 JavaScript 内部的 task 与 DOM 渲染任务有序执行,浏览器会在每个 task 执行完毕后、下一个 task 开始之前,对页面进行重新渲染(即 task -> 渲染 -> task 的循环过程)。

1.2微任务

微任务主要包括 Promise、async 以及 await。

微任务通常指在当前同步任务执行结束后立即执行的操作。这类任务常用于对一系列动作做出反馈,或者在不分配新任务的前提下执行异步逻辑,从而减少性能开销。

2.执行顺序

首先通过一段代码示例来探讨具体的执行顺序:


   console.log(1)
    setTimeout(() => {
      console.log(2)
    })
    Promise.resolve().then(() => {
      console.log(3)
    })
    console.log(4)


上述代码的打印结果为 1 4 3 2。根据运行结果,可以总结出以下执行顺序:

程序首先执行同步代码。当遇到异步宏任务时,将其放入宏任务队列;遇到异步微任务时,将其放入微任务列表。当所有同步代码执行完毕后,系统会先从微任务列表中取出异步微任务调入主线程执行。待所有微任务执行完毕后,再从宏任务队列中取出异步宏任务调入主线程执行。这一过程循环往复,直到所有任务执行完毕。

注意:微任务的执行优先于页面渲染。

3.任务关系

宏任务是主流执行单元。当 js 开始执行时,即开启了一个宏任务。在宏任务中逐条执行指令,宏任务可以有多个,但会按顺序依次执行。

每个宏任务执行完毕后,可以跟随一个微任务队列。如果该微任务队列中包含指令或方法,则优先执行;如果没有,则开始执行下一个宏任务,直到所有宏任务执行完毕。

4.任务详解

既然已有宏任务,为何还需要微任务?主要原因是宏任务的开销较大。当某些方法早已准备就绪,希望排在最后执行,但又不想新增一个宏任务时,可以将这些方法放入微任务队列中。在当前宏任务的代码执行完毕后,便会执行微任务队列中的内容。

因此,当当前同步代码执行遇到异步任务时,如果是异步宏任务,它会被放入下一轮的宏任务队列;如果是异步微任务,则被放入微任务队列,紧跟在当前宏任务之后。微任务相当于宏任务的“小尾巴”,当前宏任务执行完后,其后面等待的异步微任务会立即被放入队列继续执行。而异步宏任务需等待下一轮,这就造成了异步操作中微任务先于宏任务执行的现象。

到此这篇关于 JavaScript 微任务和宏任务讲解的文章就介绍到这了,更多相关 JavaScript 微任务和宏任务内容请搜索本站以前的文章或继续浏览下面的相关文章,希望大家以后多多支持本站!

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章