vue nextTickソースコード解析
13264 ワード
ソース:
nextTickは、コールバック関数とコールバック関数を実行するコンテキスト環境(ctx、フルネームExecution Context)の2つのパラメータを受信するコードの実行を遅延させるために使用され、コールバック関数が指定されていない場合はpromiseオブジェクトに戻ります.
なぜコードの実行を遅らせる必要があるのかについては、vue政府もVueがDOM更新を非同期で実行すると説明した.データの変化が観察される限り、Vueはキューを開き、同じイベントサイクルで発生したすべてのデータの変化をバッファリングします.同じwatcherが複数回トリガーされると、キューに1回のみプッシュされます.このようなバッファリング時に重複データを除去することは,不要な計算やDOM動作を回避する上で非常に重要である.次に、次のイベントループ「tick」で、Vueはキューをリフレッシュし、実際の(重複した)作業を実行します.
まず、3つの変数を定義します.callbacks:実行するコールバック関数を格納します.pending:コールバック関数を実行しているかどうかをマークします.timerFunc:コールバック関数の実行をトリガーします.
次のnexttickHandler関数は、timerFuncに値を割り当て、callbacksに格納されているすべてのコールバック関数を実行するために使用されます.
次に、vueは最適なスキームに従ってコールバックをトリガーします.1、promiseがサポートされているかどうか、もしそうであればpromiseを使用してコールバック関数を実行します.2、MutationObserverがサポートされているかどうか、もしそうであれば、MutationObserverを使用してコールバック関数を実行します.これはH 5に追加されたAPIで、DOMの変動を監視します.3、前の両方がサポートされていない場合は、最後の古い仲間、settimeoutで実行し、遅延を0に設定します.
最後に、ユーザが入力したコールバック関数と実行コンテキストを受信し、コールバック関数をcallbacksに格納するqueueNextTick関数を返します.(queueはキューの意味)
したがって、nextTick関数全体がqueueNextTickを先に実行し、timerFuncで遅延し、最後にnextTickHandlerで関数を実行します.
export const nextTick = (function () {
const callbacks = []
let pending = false
let timerFunc
function nextTickHandler () {
pending = false
const copies = callbacks.slice(0)
callbacks.length = 0
for (let i = 0; i < copies.length; i++) {
copies[i]()
}
}
if (typeof Promise !== 'undefined' && isNative(Promise)) {
var p = Promise.resolve()
var logError = err => { console.error(err) }
timerFunc = () => {
p.then(nextTickHandler).catch(logError)
if (isIOS) setTimeout(noop)
}
} else if (!isIE && typeof MutationObserver !== 'undefined' && (
isNative(MutationObserver) ||
MutationObserver.toString() === '[object MutationObserverConstructor]'
)) {
var counter = 1
var observer = new MutationObserver(nextTickHandler)
var textNode = document.createTextNode(String(counter))
observer.observe(textNode, {
characterData: true
})
timerFunc = () => {
counter = (counter + 1) % 2
textNode.data = String(counter)
}
} else {
timerFunc = () => {
setTimeout(nextTickHandler, 0)
}
}
return function queueNextTick (cb?: Function, ctx?: Object) {
let _resolve
callbacks.push(() => {
if (cb) {
try {
cb.call(ctx)
} catch (e) {
handleError(e, ctx, 'nextTick')
}
} else if (_resolve) {
_resolve(ctx)
}
})
if (!pending) {
pending = true
timerFunc()
}
if (!cb && typeof Promise !== 'undefined') {
return new Promise((resolve, reject) => {
_resolve = resolve
})
}
}
})()
nextTickは、コールバック関数とコールバック関数を実行するコンテキスト環境(ctx、フルネームExecution Context)の2つのパラメータを受信するコードの実行を遅延させるために使用され、コールバック関数が指定されていない場合はpromiseオブジェクトに戻ります.
なぜコードの実行を遅らせる必要があるのかについては、vue政府もVueがDOM更新を非同期で実行すると説明した.データの変化が観察される限り、Vueはキューを開き、同じイベントサイクルで発生したすべてのデータの変化をバッファリングします.同じwatcherが複数回トリガーされると、キューに1回のみプッシュされます.このようなバッファリング時に重複データを除去することは,不要な計算やDOM動作を回避する上で非常に重要である.次に、次のイベントループ「tick」で、Vueはキューをリフレッシュし、実際の(重複した)作業を実行します.
まず、3つの変数を定義します.callbacks:実行するコールバック関数を格納します.pending:コールバック関数を実行しているかどうかをマークします.timerFunc:コールバック関数の実行をトリガーします.
次のnexttickHandler関数は、timerFuncに値を割り当て、callbacksに格納されているすべてのコールバック関数を実行するために使用されます.
次に、vueは最適なスキームに従ってコールバックをトリガーします.1、promiseがサポートされているかどうか、もしそうであればpromiseを使用してコールバック関数を実行します.2、MutationObserverがサポートされているかどうか、もしそうであれば、MutationObserverを使用してコールバック関数を実行します.これはH 5に追加されたAPIで、DOMの変動を監視します.3、前の両方がサポートされていない場合は、最後の古い仲間、settimeoutで実行し、遅延を0に設定します.
最後に、ユーザが入力したコールバック関数と実行コンテキストを受信し、コールバック関数をcallbacksに格納するqueueNextTick関数を返します.(queueはキューの意味)
したがって、nextTick関数全体がqueueNextTickを先に実行し、timerFuncで遅延し、最後にnextTickHandlerで関数を実行します.