click 事件中的宏任务和微任务

Posted 在厕所喝茶

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了click 事件中的宏任务和微任务相关的知识,希望对你有一定的参考价值。

代码

我们先来看如下的代码:

<body>
  <button id="button">点击</button>
</body>
const buttonElement = document.querySelector("#button");
buttonElement.addEventListener("click", function funcA() 
  queueMicrotask(() => 
    console.log("queueMicrotask 1");
  );
  console.log("1");
);
buttonElement.addEventListener("click", function funcB() 
  queueMicrotask(() => 
    console.log("queueMicrotask 2");
  );
  console.log("2");
);

click 事件场景

首先我们有两种场景,第一种就是用户点击页面上的button按钮,触发click事件;第二种就是使用js代码,触发button按钮的click事件,也就是执行buttonElement.click()这行代码。然而,这两种场景下的输出却是不一样的。

场景一(用户点击button按钮)输出如下:1 -> queueMicrotask 1 -> 2 -> queueMicrotask 2

场景二(使用js代码触发click事件):1 -> 2 -> queueMicrotask 1 -> queueMicrotask 2

分析

场景一(用户点击button按钮)

click事件是宏任务,funcAfuncB也都是宏任务,queueMicrotask是微任务。funcAfuncB是串行执行的,先执行funcA,然后再执行funcB的。执行流程如下:

  • 执行funcA

    • queueMicrotask是微任务,将任务推到微任务队列
    • console.log("1")是同步任务,放到主执行栈中执行,控制台中输出1
  • funcA执行完毕(也就是一次宏任务执行完毕),此时需要检查微任务队列中是否存在微任务,有就需要把所有微任务执行完毕,再开始执行下一轮宏任务(也就是执行funcB)。因为funcA再执行的时候产生了一个微任务,所以微任务队列中是存在微任务的,所以就会执行微任务,控制台中输出queueMicrotask 1

  • 执行funcB

funcB的执行跟funcA同理,这里不在多叙述

场景二(使用js代码触发click事件)

使用js代码触发click事件的时候,虽然有funcAfuncB两个宏任务,但是因为微任务会监听回调之间的执行,click事件是同步分发的,导致微任务监听不到回调的执行,微任务会在监听器之后执行。简单来说funcAfuncB在执行的时候,浏览器会把他们打包在一起,当做一个宏任务去执行。实际上代码可以理解为如下:

function funcA() 
  queueMicrotask(() => 
    console.log("queueMicrotask 1");
  );
  console.log("1");


function funcB() 
  queueMicrotask(() => 
    console.log("queueMicrotask 2");
  );
  console.log("2");


funcA();
funcB();

执行流程如下:

  • 执行funcA

    • queueMicrotask是微任务,将任务推到微任务队列
    • console.log("1")是同步任务,放到主执行栈中执行,控制台中输出1
  • funcA执行完毕,因为后面还有代码(一个宏任务还没执行完毕),还需要继续往下面执行,不会去执行微任务队列中的微任务(跟场景一的区别)

  • 执行funcB

    • queueMicrotask是微任务,将任务推到微任务队列
    • console.log("2")是同步任务,放到主执行栈中执行,控制台中输出2
  • funcB执行完毕,一次宏任务执行完毕。执行微任务,控制台分别输出queueMicrotask 1queueMicrotask 2

区别

场景一和场景二的区别在于,场景一funcA是一个宏任务,funcB也是一个宏任务。场景二因为微任务监听不到回调的执行,所以funcAfuncB合并为一个宏任务。所以最终导致微任务执行的时机不一样

以上是关于click 事件中的宏任务和微任务的主要内容,如果未能解决你的问题,请参考以下文章

js中的宏任务和微任务详细讲解

经久不衰的话题:Js的宏任务(marcroTask)和微任务(microTask)

经久不衰的话题:Js的宏任务(marcroTask)和微任务(microTask)

经久不衰的话题:Js的宏任务(marcroTask)和微任务(microTask)

js中的宏任务和微任务

❤️一起谈一谈js中的宏任务和微任务!