1. 程式人生 > 其它 >vue原始碼閱讀筆記2——nextTick解析

vue原始碼閱讀筆記2——nextTick解析

關於nextTick的解析

這裡就涉及到Vue中對DOM的更新策略了,Vue在更新DOM時是非同步執行的。只要偵聽到資料變化,Vue將開啟一個事件佇列,並緩衝在同一事件迴圈中發生的所有資料變更。如果同一個watcher被多次觸發,只會被推入到事件佇列中一次。這種在緩衝時去除重複資料對於避免不必要的計算和DOM操作是非常重要的。然後,在下一個的事件迴圈“tick”中,Vue重新整理事件佇列並執行實際 (已去重的) 工作。 這裡我理解的是 不可能所有DOM的更新都會馬上執行 因為每一輪事件迴圈中涉及到多出更新DOM 因此在VUE內部 DOM 都是在一輪事件迴圈之後 下一輪迴圈之前開始然後處理上一輪遺留的所有DOM操作 一起進行更新
具體原始碼參考https://juejin.cn/post/6844904147804749832 主要步驟:
  1. 將nextTick中定義的回撥函式全部放置到callbacks陣列中; 內部形成一個閉包 陣列記憶體不釋放 始終添加回調 只有在第一次添加回調函式的時候會加一個pending 執行timeFunc 避免多次執行。
  2. 執行timeFunc函式;其中timeFunc函式是簡要說明是執行非同步操作 如果js支援promise 則是promise非同步回撥函式;
  3. 這個非同步回撥用於依次執行callbacks中的函式; DOM更新是同步到 這樣拿到的DOM就是最新的

 

export let isUsingMicroTask = false
if (typeof Promise !== 'undefined' && isNative(Promise)) { //判斷1:是否原生支援Promise const p = Promise.resolve() timerFunc = () => { p.then(flushCallbacks) if (isIOS) setTimeout(noop) } isUsingMicroTask = true } else if (!isIE && typeof MutationObserver !== 'undefined' && ( isNative(MutationObserver)
|| MutationObserver.toString() === '[object MutationObserverConstructor]' )) { //判斷2:是否原生支援MutationObserver let counter = 1 const observer = new MutationObserver(flushCallbacks) const textNode = document.createTextNode(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)) { //判斷3:是否原生支援setImmediate timerFunc = () => { setImmediate(flushCallbacks) } } else { //判斷4:上面都不行,直接用setTimeout timerFunc = () => { setTimeout(flushCallbacks, 0) } }
說的diff演算法比較好https://segmentfault.com/a/1190000008782928