寫文章不容易,點個讚唄兄弟 專一 Vue 源碼分享,文章分爲白話版和 源碼版,白話版助於理解工做原理,源碼版助於瞭解內部詳情,讓咱們一塊兒學習吧 研究基於 Vue版本 【2.5.17】javascript
若是你以爲排版難看,請點擊 下面連接 或者 拉到 下面關注公衆號也能夠吧java
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 不就行了
1 存在 回調數組 裏。每次調用 nextTick,便往數組裏面 push 設置的回調
2 只註冊一個 setTimeout,時間爲0,用於遍歷 回調數組,而後逐個執行子項
3 同步代碼執行完畢,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 中多麼頻繁地修改數據,最後 Vue 頁面只會更新一次
這是 Vue 和 nextTick 合做產生的結果,但又並不僅是 nextTick 起做用
根據響應式原理,你我都知道
數據 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,從而頁面只會更新一次