了解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