Vue nextTick 是何原理?

2022-03-13 09:48:02 字數 2751 閱讀 5021

面試被大神問到 nexttick **的時候,就是掛載結束的時候,可以獲取到準確的dom節點

實現的原理是什麼?今天做乙個總結回覆大神。。

先看vue原始碼的 nexttick 方法

// 宣告公共陣列,儲存nexttick**函式

var callbacks = ;
var pending = false;

// 執行timerfunc函式時執行這個**函式,處理在執行nexttick時新增的方法

function flushcallbacks ()

}

// 定義全域性的timerfunc

var timerfunc;

// nexttick作為行為槓桿,和微任務佇列,原生本地promise事件,或者是

// mutationobserver事件

// mutationobserver 事件有相容性問題,在ios >= 9.3.3 ,這個行為會被完全阻止,所

// 以,如果客戶端有promise支援的時候,我們使用promise更好

// 優先判斷是否支援promise

if (typeof promise !== 'undefined' && isnative(promise))

};isusingmicrotask = true;

// 如果是ie判斷是否支援mutationobserver

} else if (!isie && typeof mutationobserver !== 'undefined' && (

isnative(mutationobserver) ||

// phantomjs and ios 7.x

mutationobserver.tostring() === '[object mutationobserverconstructor]'

)) );

timerfunc = function () ;

isusingmicrotask = true;

} else if (typeof setimmediate !== 'undefined' && isnative(setimmediate)) ;

} else ;

} // 這裡是 nexttick 函式具體實現,$nexttick就是它

function nexttick (cb, ctx) catch (e)

} else if (_resolve)

});// 重點是這裡判斷,如果現在是在執行渲染結束的情況,渲染結束了,開始呼叫

// 上面被賦值好的 timerfunc ,執行這個函式會

// 觸發執行 flushcallbacks 這個函式,他會遍歷執行全部的callbacks

// 為什麼會有那麼多的callback呢,因為nexttick每次被執行都會在callbacks中

// 推送乙個事件,形成乙個事件組就是 callbacks

// 這裡的pending 是乙個全域性的變數,預設值false,在flushcallbacks裡會把

// pending = false;此處是乙個鎖保證nexttick僅有一次執行。

if (!pending)

// 如果沒有**函式,vue會讓nexttick返回乙個promise物件返回結果

if (!cb && typeof promise !== 'undefined') )

}}

看到這裡,差不多明白是在選擇乙個可以是微任務或者巨集任務的事件,找到這個事件等待nexttick觸發。

還有一部分**是在收集nexttick方法的**函式

等待時機在有一部分**執行這些函式。

還有一處不太明白,mutationobserver ios5.1之前不支援,ie只有11支援,谷歌大部分支援,支援率還是很高的。

但是如何使用這個api呢?繼續看

vue用到了mutationobserver,在使用中可以觀察一部分你想觀察的節點組,

還可以設定有哪些特性發生變化的時候**函式會獲取到。

// 找到乙個要去觀察的節點

// 配置中新增需要觀察的項

var config = ;

// 節點發生變化,**函式會被執行

var callback = function(mutationslist)

else if (mutation.type == 'attributes')

}};// 建立乙個觀察dom變化的例項,關聯到**函式,callback是關鍵必填

var observer = new mutationobserver(callback);

// 使用例項的方法把觀察的區域和專案關聯到一起

observer.observe(targetnode, config);

// 呼叫這個方法可以解除觀察,

observer.disconnect();

這裡基本上清楚了,vue裡面是觀察了一段** textnode + count 和 修改count,

如果可以執行nexttick的時候,它就去執行改變count隨後觸發 mutationobserve的**函式 flushcallbacks()。

看到這裡可以了解到基本實現原理,**事件使用了新增微任務或最差新增紅任務的方式,這個任務是在微任務佇列中的最後乙個任務

是和事件佇列有關,需要確定的就是任務執行的時機,在最後乙個微任務或者第乙個巨集任務的時候。

這樣執行**是最好的。

謝謝,不對的請指點。

vue next tick原理分析

1.爺爺元件操作孫元件的ref,用nexttick未獲取到,用settimeout可以,因此對nexttick來做 2.原始碼實現中,優先用promise mo setimedieate settimeout,為什麼微任務優於巨集任務?使用者運算元據變更後 同步任務,eg,i 100次 vue會把所...

OpenGL與OpenCL是何關係

opengl open graphics library opencl open computing language opencl和opengl是兩個不同的api。opengl是3d api。opencl是gpu通用運算api。opengl或directx是什麼呢?是負責3d圖形處理的api,包括...

什麼是DOCTYPE 它對網頁起何作用?

doctype是document type 文件型別 的簡寫,在web設計中用來說明你用的xhtml或者html是什麼版本。要建立符合標準的網頁,doctype宣告是必不可少的關鍵組成部分 除非你的xhtml確定了乙個正確的doctype,否則你的標識和css都不會生效。doctype宣告 開始製作...