您的位置:首页 > 运维架构

关于浏览器event loop 宏任务与微任务个人理解

2019-05-29 10:50 162 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/numb456/article/details/90666885

宏任务(task)

浏览器为了能够使得JS内部task与DOM任务能够有序的执行,会在一个task执行结束后,在下一个 task 执行开始前,对页面进行重新渲染 (task->渲染->task->…)此任务是不断的循环进行的。

微任务

微任务通常来说就是需要在当前 task 执行结束后立即执行的任务,比如对一系列动作做出反馈,或或者是需要异步的执行任务而又不需要分配一个新的 task,这样便可以减小一点性能的开销。只要执行栈中没有其他的js代码正在执行且每个宏任务执行完,微任务队列会立即执行。如果在微任务执行期间微任务队列加入了新的微任务,会将新的微任务加入队列尾部,之后也会被执行。

总结

微任务一定会排在当前宏任务之前,JS引擎任何任务都有队列,下面举个例子
比如你去银行窗口办理业务,那么营业员就是JS线程处理者,而排队办理业务的人就是一个个宏任务,为什么微任务总是在宏任务之前,这就好比你前面的人正在处理业务,处理完后营业员会问还有什么需要办理的业务吗?此时这个人说不定还会办理其他业务,此时后面的人还会一直等着,等此人所有业务结束后方可进行下一步,这就是宏任务嵌套微任务,微任务当然也可以嵌套宏任务,但是此时JS引擎处理队列的顺序会有所不同,若微任务嵌套宏任务 就相当于在银行办理业务的时候这个人突然想到朋友也需要办理业务给朋友打电话叫朋友也来办理业务,而此时朋友来了肯定不能插队,会排在后面,所以说等前面所有人都办完业务才会给此人朋友办理业务,这也就是宏任务被嵌套在微任务内。

那么如何区分宏任务还是微任务

一般来讲 JS定时器方法属于宏任务,微任务最典型的就是ES6 中的promise实例

代码示例

废话不多说直接上

代码
.

// 代码执行顺序
setTimeout(function(){
console.log(1)
new Promise(function(resolve,reject){
resolve()
}).then(function(res){
console.log(2)
setTimeout(function(){
console.log(5)
},1)
})
},1000)
setTimeout(function(){
console.log(3)
new Promise(function(resolve,reject){
resolve()
}).then(function(res){
console.log(4)
setTimeout(function(){
console.log(6)
},1)
})
},1000)

JS引擎属于单线程,代码自上而下进行处理,第一个定时器先进行处理所以先输出1,而后遇到promise对象,上述已经说了,promise属于微任务,所以优先级比宏任务高,紧接着输出2,其次当前promise的then回调中又嵌套了一个定时器,这个相当于去银行办理业务突然打电话让朋友也过来办理业务,所以此时JS引擎会把此处的定时器任务放到当前宏任务队列之后,而此时在处理第二个宏任务内的回调,所以此时输出3 同时此定时器内又嵌套个微任务 所以紧接着执行promise回调输出4 ,此时线程发现此回调内还有个定时器 ,就相当于在银行办理业务排在第二位的那位也叫来了他的朋友 ,那肯定他的朋友是排在刚才第一位叫来朋友的后面 所以此时线程处理第一位叫来的朋友的业务,所以输出5 最后在处理第二位叫来朋友的业务,最后输出6 ,所以此时JS线程处理顺序也就是123456

3ff7
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: