面試被大神問到 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宣告 開始製作...