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
事件是宏任务,funcA
和funcB
也都是宏任务,queueMicrotask
是微任务。funcA
和funcB
是串行执行的,先执行funcA
,然后再执行funcB
的。执行流程如下:
-
执行
funcA
queueMicrotask
是微任务,将任务推到微任务队列console.log("1")
是同步任务,放到主执行栈中执行,控制台中输出1
-
funcA
执行完毕(也就是一次宏任务执行完毕),此时需要检查微任务队列中是否存在微任务,有就需要把所有微任务执行完毕,再开始执行下一轮宏任务(也就是执行funcB
)。因为funcA
再执行的时候产生了一个微任务,所以微任务队列中是存在微任务的,所以就会执行微任务,控制台中输出queueMicrotask 1
-
执行
funcB
funcB
的执行跟funcA
同理,这里不在多叙述
场景二(使用js
代码触发click
事件)
使用js
代码触发click
事件的时候,虽然有funcA
和funcB
两个宏任务,但是因为微任务会监听回调之间的执行,click
事件是同步分发的,导致微任务监听不到回调的执行,微任务会在监听器之后执行。简单来说funcA
和funcB
在执行的时候,浏览器会把他们打包在一起,当做一个宏任务去执行。实际上代码可以理解为如下:
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 1
,queueMicrotask 2
区别
场景一和场景二的区别在于,场景一funcA
是一个宏任务,funcB
也是一个宏任务。场景二因为微任务监听不到回调的执行,所以funcA
和funcB
合并为一个宏任务。所以最终导致微任务执行的时机不一样
以上是关于click 事件中的宏任务和微任务的主要内容,如果未能解决你的问题,请参考以下文章
经久不衰的话题:Js的宏任务(marcroTask)和微任务(microTask)
经久不衰的话题:Js的宏任务(marcroTask)和微任务(microTask)