JS event queue

最近毕设碰到的一个问题

我向dom中添加一个节点,然后使滚动条滚动到底部
很简单的一个需求,但是做的时候发现,window.scrollTo(0,dom.scrollHeight)并没有像想象中一样使滚动条底部,而节点的确已经添加进去了。

原因:浏览器加载机制js在css之前,当添加节点的js执行之后,节点并没有立即添加到页面,因为还有同步的js代码没有执行,js线程阻塞了GUI渲染线程,所以当执行window.scrollTo的时候,并没有跳到页面底部。

解决方法:将调到底部的window.scrollTo(0,dom.scrollHeight)设为异步执行,异步执行的函数不会阻塞线程,而是等待所有同步代码执行完毕后,才开始异步队列函数的执行,因此通过setTimeout(fn,0),当vue中diff算法(需要时间,并且在跳转之前并未完成,vue使用的就是nexttick,在settimeout之前执行)操作,浏览器渲染完毕后,主线程空出才会执行该跳转代码。

Vue是异步执行dom更新的,一旦观察到数据变化,Vue就会开启一个队列,然后把在同一个事件循环 (event loop) 当中观察到数据变化的 watcher 推送进这个队列,所以数据变更后想要立即操作dom,需要把操作写在同一个队列的异步操作中,或者写在下一个Vue.nextTick()中。

在node中还存在process.nextTick/setImmediate控制代码在事件队列中的执行,执行顺序为
执行队列--->process.nextTick(fn)--->setTimeout ~= setlmmediate

你可能感兴趣的:(JS event queue)