這期內(nèi)容當(dāng)中小編將會(huì)給大家?guī)碛嘘P(guān)NextTick的作用有哪些,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
電白ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場景,ssl證書未來市場廣闊!成為創(chuàng)新互聯(lián)的ssl證書銷售渠道,可以享受市場價(jià)格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:13518219792(備注:SSL證書合作)期待與您的合作!
在vue中每次監(jiān)聽到數(shù)據(jù)變化的時(shí)候,都會(huì)去調(diào)用notify通知依賴更新,觸發(fā)watcher中的update方法。
update () { /* istanbul ignore else */ if (this.lazy) { } else if (this.sync) { } else { this.get() //queueWatcher(this) } }
如果通過watcher中的get方法去重新渲染組件,那么在渲染的過程中假如多次更新數(shù)據(jù)會(huì)導(dǎo)致同一個(gè)watcher被觸發(fā)多次,這樣會(huì)導(dǎo)致重復(fù)的數(shù)據(jù)計(jì)算和DOM的操作。如下圖所示,修改3次message之后DOM被操作了3次。
為了解決上述問題,不去直接調(diào)用get方法而是將每次調(diào)用update方法后需要批處理的wather暫存到一個(gè)隊(duì)列當(dāng)中,如果同一個(gè) watcher 被多次觸發(fā),通過wacther 的id屬性對其去重,只會(huì)被推入到隊(duì)列中一次。然后,等待所有的同步代碼執(zhí)行完畢之后在下一個(gè)的事件循環(huán)中,Vue 刷新隊(duì)列并執(zhí)行實(shí)際 (已去重的) 工作。
let has: { [key: number]: ?true } = {} let waiting = false export function queueWatcher (watcher: Watcher) { const id = watcher.id //對watcher去重 if (has[id] == null) { has[id] = true queue.push(watcher); if (!waiting) { //節(jié)流 waiting = true nextTick(flushSchedulerQueue) } }
調(diào)用watcher的run方法異步更新DOM
let has: { [key: number]: ?true } = {} function flushSchedulerQueue () { let watcher, id queue.sort((a, b) => a.id - b.id) for (index = 0; index < queue.length; index++) { watcher = queue[index] if (watcher.before) { watcher.before() } id = watcher.id has[id] = null //清空id watcher.run() //更新值 } resetSchedulerState() //清空watcher隊(duì)列 } function resetSchedulerState () { index = queue.length = 0 has = {} waiting = false }
在vue內(nèi)部調(diào)用nextTick(flushSchedulerQueue),vm.$nextTick方法調(diào)用的也是nextTick()方法
Vue.prototype.$nextTick = function (cb) { nextTick(cb,this); };
那么多次調(diào)用nextTick方法是怎么處理的呢?
const callbacks = [] let pending = false export function nextTick (cb?: Function, ctx?: Object) { callbacks.push(() => { if (cb) { try { cb.call(ctx) } catch (e) { handleError(e, ctx, 'nextTick') } } }) if (!pending) { pending = true timerFunc() } }
nextTick將所有的回調(diào)函數(shù)暫存到了一個(gè)隊(duì)列中,然后通過異步調(diào)用更新去依次執(zhí)行隊(duì)列中的回調(diào)函數(shù)。
function flushCallbacks () { pending = false const copies = callbacks.slice(0) callbacks.length = 0 for (let i = 0; i < copies.length; i++) { copies[i]() } }
nextTick函數(shù)中異步更新對兼容性做了處理,使用原生的 Promise.then、MutationObserver 和 setImmediate,如果執(zhí)行環(huán)境不支持,則會(huì)采用 setTimeout(fn, 0) 代替。
Promise
if (typeof Promise !== 'undefined' && isNative(Promise)) { const p = Promise.resolve() timerFunc = () => { p.then(flushCallbacks) } }
MutationObserver
MutationObserver 它會(huì)在指定的DOM發(fā)生變化時(shí)被調(diào)用。創(chuàng)建了一個(gè)文本DOM,通過監(jiān)聽字符值的變化,當(dāng)文本字符發(fā)生變化的時(shí)候調(diào)用回調(diào)函數(shù)。
if (!isIE && typeof MutationObserver !== 'undefined' && ( isNative(MutationObserver) || MutationObserver.toString() === '[object MutationObserverConstructor]' )) { 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) } }
setImmediate
setImmediate該方法用作把一些需要持續(xù)運(yùn)行的操作放在一個(gè)其他函數(shù)里,在瀏覽器完成后面的其他語句后,就立即執(zhí)行此替換函數(shù)。
if (typeof setImmediate !== 'undefined' && isNative(setImmediate)) { timerFunc = () => { setImmediate(flushCallbacks) } }else{ timerFunc = () => { setTimeout(flushCallbacks, 0) } }
總結(jié)
vue渲染DOM的時(shí)候觸發(fā)set方法中的去依賴更新,在更新的過程中watcher不是每次都去執(zhí)行去觸發(fā)DOM的更新,而是通過對wather的去重之后,通過nextTick異步調(diào)用觸發(fā)DOM更新。
nextTick()就是一個(gè)異步函數(shù),在異步函數(shù)中通過隊(duì)列批處理nextTick傳入的回調(diào)函數(shù)cb,但是隊(duì)列彼此不是同時(shí)進(jìn)行的,通過節(jié)流的方式依次執(zhí)行。
上述就是小編為大家分享的NextTick的作用有哪些了,如果剛好有類似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。
文章題目:NextTick的作用有哪些
本文網(wǎng)址:http://muchs.cn/article48/iejoep.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站設(shè)計(jì)公司、外貿(mào)建站、面包屑導(dǎo)航、、動(dòng)態(tài)網(wǎng)站、營銷型網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)