Eventloop机制和大量dom操作分时

本着多深入一点点的原则,今天看到了一个问题,是关于js如何实现精确计时,这个暂且不在这篇文章中讨论,想说的是在查阅资料的时候看到了一篇文章讨论了浏览器的运行机制。

文章提及了事件监听和setTimeout的定时器实际上是两个独立于js主线程的线程。这跟我之前看阮一峰的eventloop机制讲解的文章自己理解的内容有一点偏差。经过自己的思考,我认为阮一峰的博文有一定的问题,这个问题是出于其本身的错误还是没有明确细节使人产生了误解并不重要,重要的还是要确认自己的理解是否正确。

按照我目前的理解,这两个独立线程的说法是正确的,也就是说实际上setTimeout和事件监听机制确实可以说是实时根据判断条件捕获到了,真正出现延迟的是其回调函数!

eventloop的待办事件队列中存放的并非是setTimout函数,而是其回调函数!当时间条件判断成功后,这个队列就加入了其回调函数,但是由于js是单线程的,所以要等到执行栈中的同步任务处理完毕才能从队列中读取异步任务。

而我之前看完阮一峰的文章得出的结论是队列中存放的时setTimout,当执行栈空闲再去进行判断,虽然也能自圆其说,但实际上却是完全错误的!

温故而知新,确实如此。

基于以上理解和js主线程与gui线程互斥,我想在前端常见的一个大量数据加载并操作dom显示如何防止页面失去响应的问题也很好理解了。

之所以失去响应,原因是js引擎主线程和gui线程是互斥的。凡是互斥,应当都是他们之间存在可能同时改变的状态,因为js会进行dom操作,所以这跟页面渲染可能是出现冲突的。当大量dom操作发生时,gui需要等待js更新dom,所以此时页面失去了响应。

为了解决这个问题,我们还是需要回到js运行机制上。如何使js中dom操作的语句和gui线程不同时进行,那么也就不会出现冲突。核心思想是借助setTimeout进行分时操作,把插入dom的语句分开执行,这样运行栈中没有其他同步任务,而待办队列由于事件条件所以没有加入回调函数,整个js主线程是空闲的,gui线程就可以进行及时更新了。

not found!