nextTick()
nextTick是什么?
等待下一次DOM更新刷新的工具方法;
类型: function nextTick(callback?: () => void): Promise
JS的运行机制
单线程执行机制,基于事件循环
能力检测
1.首先检测符合的执行环境
1)先检测微任务(micro task)
经过以上判断微任务是否支持原生Promise,原生MutationObserver的执行环境,若都不支持,则表示当前浏览器不支持微任务;
2)再宏任务的检测(macro task)
判断宏任务是否支持原生 setImmediate;
3)若以上都不支持,则使用setTimeOut
执行回调队列
当传入回调函数cb后,对panding进行判断,若为false,则进行timerFunc的对应方法检测,否则将回调函数推入回调队列,并进行判断。
若回调函数cb未传入,则返回一个Promise.resolve()
个人知识点补充
在vue2当中的应用: this.$nextTick(()=>{})
在源码中,直接调用了nextTick,未调用$nextTick:
这是因为做了代理,挂载到了$上.
知识补充:代理模式 代理模式:(Proxy Pattern),是程序设计的一种设计模式。在代理模式中,一个类代表另一个类的功能。这种类型的设计模式属于结构型模式。 在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口。
在vue中的做代理有:Object.defineProperty()
代理模式举例:
知识扩充:【1.: 在Vue生命周期的created()钩子函数进行的DOM操作一定要放在Vue.nextTick()的回调函数中
在 Vue生命周期函数中 created钩子函数中: DOM 并没有进行任何渲染, 而此时进行DOM 操作无异于是徒劳的, 所以此处一定将DOM 操作的js 代码放进Vue.nextTick 回调函数中, 与之对应的就是mounted() 钩子函数, 因为该钩子函数执行时所有的DOM 挂载和渲染都已经完成, 此时在该钩子函数中进行任何操作都不会有问题。
2.: 在数据变化后要执行某个回调函数,而这个操作需要使用随数据改变而改变的DOM结构的时候, 这个操作都应该放进Vue.nextTick () 回调函数中。
3.: Vue的官方文档中详细解释: vue 执行dom 更新是异步的, 只要是观察到数据变化, vue 将会开启一个队列, 并缓冲在同一事件循环中发生的所有数据改变。 如果同一个watcher 被多次触发,只会被推到队列中一次。 在这种缓冲时去除重复数据对于避免不必要的计算, 和DOM 操作非常重要。 然后下一个事件循环 “tick”中, vue 刷新队列执行实际(去重)工作。 在Vue 内部尝试对异步队列使用原生的promise.then 和 MessageChange, 如果执行环境不支持, 会采用setTime(()=> {} , 0)代替。】
callbacks:用来存储所有需要执行的回调函数
pending:用来标志是否正在执行回调函数
timerFunc:用来触发执行回调函数