当前位置: 首页 > article >正文

#JavaScript 宏任务与微任务详解

一、什么是宏任务和微任务?

1.1 宏任务(Macro Task)

  • 宏任务是 JavaScript 中的最外层任务,它包括了浏览器中几乎所有的常见操作,如

    • setTimeout 和 setInterval 中的回调函数
    • DOM 渲染
    • 网络请求的回调(如 AJAX)
    • 用户输入(键盘事件、鼠标事件等)
  • 每当 JavaScript 引擎执行一个宏任务时,它会按照以下步骤进行

    • 从宏任务队列中取出第一个任务。
    • 执行这个任务,直到它完成。
    • 然后开始下一个宏任务。

1.2 微任务(Micro Task)

  • 微任务是在宏任务执行完毕后、下一次事件循环开始前执行的一类任务。微任务通常用于处理一些比宏任务优先级更高的操作,比如:

    • Promise 的 .then() 或 .catch() 回调
    • MutationObserver(用于监听 DOM 变化)
  • 微任务队列的执行顺序优先于宏任务,且在宏任务执行前,如果微任务队列不为空,所有微任务会被执行完毕。

二、事件循环(Event Loop)

JavaScript 是单线程的,这意味着它只能在同一时刻执行一个任务。事件循环机制负责在执行完当前任务后,从任务队列中取出下一个任务并执

  • JavaScript 的事件循环有一个明确的执行顺序。事件循环每次迭代的顺序如下:
    • 执行栈:首先执行当前正在执行的代码。
    • 宏任务队列:执行一个宏任务队列中的任务。
    • 微任务队列:执行所有的微任务,直到队列为空。
    • 渲染更新:在所有任务完成后,浏览器可能会进行渲染更新。
    • 下一轮事件循环。

三、宏任务与微任务执行顺序

console.log('Start');

setTimeout(() => {
  console.log('Macro Task 1');
}, 0);

Promise.resolve().then(() => {
  console.log('Micro Task 1');
}).then(() => {
  console.log('Micro Task 2');
});

setTimeout(() => {
  console.log('Macro Task 2');
}, 0);

console.log('End');

// Start
// End
// Micro Task 1
// Micro Task 2
// Macro Task 1
// Macro Task 2
执行过程:
  1. 首先,console.log(‘Start’) 被执行,输出:Start。
  2. 接着,setTimeout 被调用,Macro Task 1 会被推入宏任务队列,但它将在当前执行栈清空后才会执行。
  3. 然后,Promise.resolve().then() 被调用,Micro Task 1 会被推入微任务队列,紧接着 then() 中的第二个回调 Micro Task 2 也被加入微任务队列。
    4.setTimeout 再次被调用,Macro Task 2 会被推入宏任务队列。
  4. console.log(‘End’) 被执行,输出:End。
  5. 由于当前执行栈已经空了,开始执行微任务:
  • Micro Task 1 被执行,输出:Micro Task 1。
  • Micro Task 2 被执行,输出:Micro Task 2。
  1. 最后,宏任务队列中的任务开始执行:
  • Macro Task 1 被执行,输出:Macro Task 1。
  • Macro Task 2 被执行,输出:Macro Task 2。

四、宏常见问题与误解

5.1 为什么 setTimeout 不会立即执行?

即使你设置了 setTimeout(callback, 0),它也不会在当前执行栈清空后立即执行。它仍然是一个宏任务,意味着它会等待当前执行栈中的代码执行完毕,然后才会进入事件循环执行

5.2 微任务可以"阻塞"宏任务吗?

是的,微任务可以阻塞宏任务。在事件循环过程中,如果微任务队列不为空,微任务会一直被执行,直到队列为空。因此,如果在微任务中加入一个无限循环的微任务,它将阻塞后续的宏任务执行。


http://www.kler.cn/a/382628.html

相关文章:

  • SQL进阶技巧:如何计算复合增长率?
  • 论文阅读笔记:DRCT: Saving Image Super-Resolution away from Information Bottleneck
  • 论文阅读:DynamicDet: A Unified Dynamic Architecture for Object Detection
  • Python练习8
  • 详解:字符串常量池
  • 利用pythonstudio写的PDF、图片批量水印生成器,可同时为不同读者生成多组水印
  • 2-146 基于matlab的双摆杆系统建模分析
  • Tomcat 启动卡住,日志显示 At least one JAR was scanned for TLDs yet contained no TLDs.
  • 【C语言】实战-力扣题库:回文链表
  • 【LeetCode】【算法】238. 除自身以外数组的乘积
  • Hadoop集群的高可用(HA)-(2、搭建resourcemanager的高可用)
  • dbt 数据分析工程实战教程(汇总篇)
  • Mill:比Maven快10倍的JVM构建工具
  • 如何理解美国总统Trump这个单词
  • 数据库SQL学习笔记
  • OpenCV C++ 计算两幅图像之间的多尺度结构相似性(MSSIM)
  • 前端八股文(三)JS、ES6 持续更新中。。。
  • pycharm小游戏贪吃蛇及pygame模块学习()
  • ORB-SLAM2源码学习:ORBextractor.cc:ComputePyramid构建图像金字塔①
  • 【C/C++】模拟实现strcat
  • Pr 视频过渡:沉浸式视频 - VR 光线
  • git 提交管理
  • ArcGIS006:ArcMap常用操作151-200例动图演示
  • Go构造函数的实现
  • 如何设置内网IP的端口映射到公网
  • Java+Swing可视化图像处理软件