18-宏任务和微任务:不是所有任务都是⼀个待遇18-宏任务和微任务:不是所有任务都是⼀个待遇
在前⾯⼏篇⽂章中,我们介绍了消息队列,并结合消息队列介绍了两种典型的WebAPI⸺setTimeoutsetTimeout和
XMLHttpRequestXMLHttpRequest,通过这两个WebAPI我们搞清楚了浏览器的消息循环系统是怎么⼯作的。不过随着浏览
器的应⽤领域越来越⼴泛,消息队列中这种粗时间颗粒度的任务已经不能胜任部分领域的需求,所以⼜出现
了⼀种新的技术⸺微任务微任务。微任务可以在实时性和效率之间做⼀个有效的权衡微任务可以在实时性和效率之间做⼀个有效的权衡。
从⽬前的情况来看,微任务已经被⼴泛地应⽤,基于微任务的技术有MutationObserver、Promise以及以
Promise为基础开发出来的很多其他的技术。所以微任务的重要性也与⽇俱增,了解其底层的⼯作原理对于
你读懂别⼈的代码,以及写出更⾼效、更具现代的代码有着决定性的作⽤。
有微任务,也就有宏任务,那这⼆者到底有什么区别?它们⼜是如何相互取⻓补短的?
宏任务宏任务
前⾯我们已经介绍过了,⻚⾯中的⼤部分任务都是在主线程上执⾏的,这些任务包括了:
为了协调这些任务有条不紊地在主线程上执⾏,⻚⾯进程引⼊了消息队列和事件循环机制,渲染进程内部会
维护多个消息队列,⽐如延迟执⾏队列和普通的消息队列。然后主线程采⽤⼀个for循环,不断地从这些任
务队列中取出任务并执⾏任务。我们把这些消息队列中的任务称为宏任务宏任务。
消息队列中的任务是通过事件循环系统来执⾏的,这⾥我们可以看看在WHATWG规范中是怎么定义事件循
环机制的。
由于规范需要⽀持语义上的完备性,所以通常写得都会⽐较啰嗦,这⾥我就⼤致总结了下WHATWG规范定
义的⼤致流程:
以上就是消息队列中宏任务的执⾏过程,通过前⾯的学习,相信你也很熟悉这套执⾏流程了。
宏任务可以满⾜我们⼤部分的⽇常需求,不过如果有对时间精度要求较⾼的需求,宏任务就难以胜任了,下
⾯我们就来分析下为什么宏任务难以满⾜对时间精度要求较⾼的任务。
前⾯我们说过,⻚⾯的渲染事件、各种IO的完成事件、执⾏JavaScript脚本的事件、⽤⼾交互的事件等都随
时有可能被添加到消息队列中,⽽且添加事件是由系统操作的,JavaScript代码不能准确掌控任务要添加到
队列中的位置,控制不了任务在消息队列中的位置,所以很难控制开始执⾏任务的时间。为了直观理解,你
渲染事件(如解析DOM、计算布局、绘制);
⽤⼾交互事件(如⿏标点击、滚动⻚⾯、放⼤缩⼩等);
JavaScript脚本执⾏事件;
⽹络请求完成、⽂件读写完成事件。
先从多个消息队列中选出⼀个最⽼的任务,这个任务称为oldestTask;
然后循环系统记录任务开始执⾏的时间,并把这个oldestTask设置为当前正在执⾏的任务;
当任务执⾏完成之后,删除当前正在执⾏的任务,并从对应的消息队列中删除掉这个oldestTask;
最后统计执⾏完成的时⻓等信息。
评论0
最新资源