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合并为一个宏任务。所以最终导致微任务执行的时机不一样

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值