nextTick的实现原理是什么?
在下次DOM更新循环结束之后执⾏的延迟回调。
根据执⾏环境分别尝试采⽤⽤微任务,再是宏任务
Promise的then -> MutationObserver的回调函数 -> setImmediate -> setTimeout 是否存在,到存在的就调⽤他childrenRef
作⽤:
nextTick⽤于下次Dom更新循环结束之后执⾏延迟回调,在修改数据之后使⽤nextTick⽤于下次Dom更新循环结束之后执⾏延迟回调,在修改数据之后使⽤nextTick⽤于下次Dom更新循环结束之后执⾏延迟回调,在修改数据之后使⽤nextTick,则可以在回调中获取更新后的DOM。
应⽤场景:
需要在视图更新之后,基于新的视图进⾏操作。
实现原理:
nextTick⽅法主要是使⽤了宏任务和微任务,定义了⼀个异步⽅法,多次调⽤nextTick会将⽅法存⼊队列中,通过这个异步⽅法清空队列。
VUE中nextTick实现原理
在vue中有nextTick这个API,官⽅解释,它可以在DOM更新完毕之后执⾏⼀个回调。
⼀般使⽤
this.$nextTick(() => {
...
})
⼀般来说,在对于MVVM框架结构的技术栈是不推荐操作DOM的,但是很多情况下可能会需要操作DOM,特别是⼀些charts插件等。
所以nextTick就出现了,确保我们所操作的DOM是更新之后的。
那VUE是如何知道DOM什么时候更新完了呢?
VUE源码:(把⾥⾯的注释都删掉了)
if (typeof Promise !== 'undefined' && isNative(Promise)) {
const p = solve()
timerFunc = () => {
p.then(flushCallbacks)
if (isIOS) setTimeout(noop)
}
isUsingMicroTask = true
} else if (!isIE && typeof MutationObserver !== 'undefined' && (
isNative(MutationObserver) ||
)
) {
nodejs到底是干嘛用的呢let counter = 1
const observer = new MutationObserver(flushCallbacks)
const textNode = ateTextNode(String(counter))
observer.observe(textNode, {
characterData: true
})
timerFunc = () => {
counter = (counter + 1) % 2
textNode.data = String(counter)
}
isUsingMicroTask = true
} else if (typeof setImmediate !== 'undefined' && isNative(setImmediate)) {
timerFunc = () => {
setImmediate(flushCallbacks)
}
} else {
timerFunc = () => {
setTimeout(flushCallbacks, 0)
}
}
步骤:
先判断Promise
在判断MutationObserver
在判断setImmediate
最后setTimeout
整体流程涉及到事件的循环(Event Loop)[暂不在这说]
每次event loop的最后,会有⼀个UI render,也就是更新DOM
只要让nextTick⾥的代码放在UI render步骤后⾯执⾏,就能访问到更新后的DOM了。
⼜涉及到微任务(microtask)和宏任务(macrotask)
microtask有:Promise、MutationObserver,以及nodejs中的Tick
macrotask有:setTimeout, setInterval, setImmediate, I/O, UI rendering
每⼀次事件循环都包含⼀个microtask队列,在循环结束后会依次执⾏队列中的microtask并移除,然后再开始下⼀次事件循环。
vue的nextTick⽅法的实现原理:
vue⽤异步队列的⽅式来控制DOM更新和nextTick回调先后执⾏
microtask因为其⾼优先级特性,能确保队列中的微任务在⼀次事件循环前被执⾏完毕
因为浏览器和移动端兼容问题,vue不得不做了microtask向macrotask的兼容(降级)⽅案

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。