【Vue原理】NextTick - 白話版

寫文章不容易,點個讚唄兄弟 專一 Vue 源碼分享,文章分爲白話版和 源碼版,白話版助於理解工做原理,源碼版助於瞭解內部詳情,讓咱們一塊兒學習吧 研究基於 Vue版本 【2.5.17】javascript

若是你以爲排版難看,請點擊 下面連接 或者 拉到 下面關注公衆號也能夠吧java

【Vue原理】NextTick - 白話版 數組

nextTick 是 Vue 中比較重要的一部分,源碼獨立而簡短,稍做修改就能夠拿出來爲你的項目服務, 我已經有在項目中使用了promise

想必你們寫 Vue 項目的時候,應該也有使用過 nextTick異步

通常我是用在數據渲染完畢以後執行某些操做函數

this.list =[xx,xx,xx]

this.$nextTick(()=>{    

    this.isLoading=false

})

nextTick 按個人理解,就是設置一個回調,用於異步執行oop

異步執行,好比,就是把你設置的回調放在 setTimeout 中執行,這樣就算異步了,等待當時同步代碼執行完畢再執行學習

可是,每設置一個 nextTick 就新建一個 setTimeout 又不實際,this

畢竟一個 setTimeout 是異步,兩個setTimeout 也是異步,兩個都要等在 同步代碼執行完畢以後才執行3d

那我直接只設置一個 setTimeout 不就行了


那一個 setTimeout 怎麼執行多個回調呢?

1 存在 回調數組 裏。每次調用 nextTick,便往數組裏面 push 設置的回調

2 只註冊一個 setTimeout,時間爲0,用於遍歷 回調數組,而後逐個執行子項

3 同步代碼執行完畢,setTimeout 天然會執行


Vue 不止使用 setTimeout

Vue的 nextTick 也是隻用setTimeout 嗎,不是的,這裏便會涉及到 javascript 的 宏微任務

網上有不少寫的很好的關於宏微任務的文章,你們能夠去搜索看

關於宏微任務,簡單說一下我的理解

1 二者區別在於執行權重的問題,微任務優先級要比宏任務高

2 宏任務 和 微任務 合做完成一個 Event Loop

3 執行一個 宏任務,便會執行一列微任務。接着執行另外一個宏任務...(循環往復,好比一個setTimeout 就是一個宏任務)

Vue 2.4 之前,只使用 微任務,由於微任務執行優先級高

Vue 2.5.3 以後,分紅了 宏任務 和 微任務,爲了解決連續事件帶來的問題,好比冒泡(至於爲何,會有一篇文章說明)

Vue 2.6 ,又只使用微任務,由於想到了其餘辦法解決連續事件的問題

Vue 的 宏微任務 並不算是嚴格意義上的宏微任務,是種兼容的寫法。

一般會作不少判斷來選擇存在的類型,好比判斷 promise 等是否存在,而選擇他爲微任務類型

可是可能宏微任務最後都是 setTimeout ,由於他是保守兼容處理。這樣Vue微任務實際上是宏任務了


Vue 使用了 nextTick 進行統一更新

你應該知道,即便在 Vue 中多麼頻繁地修改數據,最後 Vue 頁面只會更新一次

這是 Vue 和 nextTick 合做產生的結果,但又並不僅是 nextTick 起做用

根據響應式原理,你我都知道

【Vue原理】響應式原理 - 白話版

好比

數據 name 被 頁面引用,name 會收集到 頁面的 watcher

name 被修改時,會通知全部收集到的 watcher 進行更新(watcher.update)

this.name = 2

this.name = 3

this.name = 4

若是

name 一時間被修改三次時,按道理應該會通知三次 watcher 更新,那麼頁面會更新三次

可是最後只會更新一次

就是由於他們的合做

設置 nextTick 回調 + 過濾 watcher

當數據變化後,把 watcher.update 函數存放進 nextTick 的 回調數組中,而且會作過濾。

經過 watcher.id 來判斷 回調數組 中是否已經存在這個 watcher 的更新函數

不存在,才 push

以後 nextTick 遍歷回調數組,便會執行了更新

因此

當三次修改數據的時候,會準備 push進 回調數組 三個 watcher.update,可是隻有第一次是 push 成功的,其餘的會被過濾掉

因此,無論你修改多少次數據,nextTick 的回調數組中只存在惟一一個 watcher.update,從而頁面只會更新一次

公衆號

相關文章
相關標籤/搜索