了解js的宏任务(macrotask)和微任务(microtask)以及Event-Loop

JavaScript

首先,JavaScript是一个单线程的脚本语言,所以就是说在一行代码执行的过程中,必然不会存在同时执行的另一行代码,就像使用alert()后进行打印,如果不关闭弹窗,则不会执行后续的打印操作

微任务与宏任务的区别

宏任务:

类似于去银行办理业务,柜员同一时间只能为一个客户办理业务,因此每个客户要想办理业务就必须进行排队领号,这里的“客户”=宏任务,当柜员处理完当前客户的所有问题后,就会接待下一位客户,广播报号时也就意味着下一个宏任务的开始。多个宏任务的时候就是相当于排队的客户们。

常见宏任务:

# 浏览器 Node
setTimeout
setInterval
setImmediate x
requestAnimationFrame x

任务队列中的都是已经完成的异步操作,而不是说注册一个异步任务就会被放在任务队列中,就像银行排队叫号的时候你不在,那么就需要重新领号,柜员会直接进行下一位客户的业务处理,也就是直接进入下一个宏任务了

微任务:

在一个宏任务执行的过程中,是可以添加微任务的,类似于柜员处理当前客户的时候,客户手头不止一个需求需要得到处理,有可能有多个业务需要办理,而里面的多个业务指的就是微任务,直到当前宏任务中的微任务办理结束后才会进行下一个宏任务

常见微任务:

# 浏览器 Node
process.nextTick x
MutationObserver x
Promise.then catch finally

举例:

setTimeout(() => {
    //执行后 回调一个宏事件
    console.log('内层宏事件3')
}, 0)
console.log('外层宏事件1');

new Promise((resolve) => {
    console.log('外层宏事件2');
    resolve()
}).then(() => {
    console.log('微事件1');
}).then(()=>{
    console.log('微事件2')
})

打印结果

//外层宏事件1
//外层宏事件2
//微事件1
//微事件2
//内层宏事件3

• 首先浏览器执行js进入第一个宏任务进入主线程, 遇到 setTimeout  分发到宏任务Event Queue中

• 遇到 console.log() 直接执行 输出 外层宏事件1

• 遇到 Promise, new Promise 直接执行 输出 外层宏事件2

• 执行then 被分发到微任务Event Queue中

•第一轮宏任务执行结束,开始执行微任务 打印 '微事件1' '微事件2'

•第一轮微任务执行完毕,执行第二轮宏事件,打印setTimeout里面内容'内层宏事件3'

 

Event-Loop(只简单说一下)

正因为js是一个单进程的语言,同一时间不能处理多个任务,所以何时执行宏任务、微任务,我们就需要一个可以进行判断逻辑的存在

每次办理完一个业务,会询问当前客户是否还需要办理其他业务检查还有没微任务需要处理)

客户明确告知没有业务需要办理了,柜员会去查看后面是否还有客户需要办理业务(结束本次宏任务后,检查还有没有未处理的宏任务)

这个检查的过程是持续进行的,每完成一个任务都会进行一次,而这样的操作就被称为Event Loop

以及还要明确的是,Event Loop只是负责告诉你该执行那些任务,或者说哪些回调被触发了,真正的逻辑还是在进程中执行的。

 

参考:

https://www.cnblogs.com/jiasm/p/9482443.html

 

posted @ 2021-06-22 14:28  俩只猫  阅读(337)  评论(0编辑  收藏  举报