摘要:這么講,有點籠統,準確地說,應該是事件回調執行過程中,在主線程為空之后,異步代碼執行之前,所有通過注冊的異步代碼都是用宏任務。
寫文章不容易,點個贊唄兄弟
專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內部詳情,讓我們一起學習吧
研究基于 Vue版本 【2.5.17】
如果你覺得排版難看,請點擊 下面鏈接 或者 拉到 下面關注公眾號也可以吧
【Vue原理】NextTick - 源碼版 之 宏微任務的抉擇
nextTick 已經寫了三篇文章啦,這是最后一篇源碼版,沒看過的童鞋可以看看白話版簡單了解下拉
【Vue原理】NextTick - 白話版 簡單了解下NextTick
在前面的文章 NextTick-源碼版之獨立自身 中
埋下過兩個問題
1、Vue 在哪里使用到了 宏任務和 微任務 2、Vue 為什么需要 宏任務 和微任務
今天的任務就是解決這兩個問題!!!
在這里,大家肯定必須一定要了解了 宏任務和 微任務的哈,這兩個東西不贅述了
首先,第一個問題就是宏微任務的使用場景場景
宏微任務的使用場景1、Vue 一般情況下使用的是微任務
2、在綁定DOM 事件的時候,會使用宏任務。
這么講,有點籠統,準確地說,應該是
事件回調執行過程中,在JS 主線程為空之后,異步代碼執行之前,所有通過 nextTick 注冊的異步代碼都是用宏任務。
來看看綁定DOM 事件的源碼
通過 addEventListener 給 DOM 綁定事件
function add$1(event, handler) { handler = withMacroTask(handler); target$1.addEventListener(event, handler); } function withMacroTask(fn) { return fn._withTask || (fn._withTask = function() { useMacroTask = true; var res = fn.apply(null, arguments); useMacroTask = false; return res }) }
你看到了,把原先DOM 事件的回調包裝了一遍,然后通過設置 useMacroTask 來控制注冊宏任務
useMacroTask 沒見過,在 nextTick 獨立流程中已經講過了的
在調用 nextTick 的時候,正是通過這個變量來控制,此次異步代碼注冊的任務類型
Vue.nextTick =function (cb, ctx) { callbacks.push(function() { cb && cb.call(ctx); }); if (!pending) { pending = true; if (useMacroTask) { macroTimerFunc(); } else { microTimerFunc(); } } }
好多,現在我們來解決第二個問題!
為什么需要宏微任務為什么要特地在事件回調執行期間 使用宏任務啊,想了好好久啊,才腦抽想到去看了下 Vue 的注釋
大概意思是這樣本來 Vue 是從來都使用微任務的,因為微任務的優先級比較高,執行比較快。但是同時也是因為這樣導致了一個問題
什么問題?在連續事件發生的期間,微任務就已經執行了
就是事件回調執行完成之后,會馬上執行微任務
那么連續多個事件回調同時執行,就會導致連續多次執行微任務
如果連續多個事件回調中,都有修改數據,如下
this.state = xxxxx
那么很明顯,會導致頁面頻繁的更新,這顯然不是我們想要的結果
那到底什么是連續的事件?那就是冒泡!
我們來現場演示一下微任務下的冒泡事件
div1.onclick = function() { console.log("div1"); Promise.resolve().then(() = >{ console.log("promise1") }) } div2.onclick = function() { console.log("div2"); Promise.resolve().then(() = >{ console.log("promise2") }) } div3.onclick = function() { console.log("div3"); Promise.resolve().then(() = >{ console.log("promise3") }) }
看到了嗎,promise 在一個事件回調結束之后馬上就調用了
如果在 Vue 中的事件回調中修改了數據 this.state = xxxxx
然后數據一更改,就會注冊微任務用于響應更新,然后事件結束之后,馬上執行微任務
如果三個事件回調都有修改數據,那么就會注冊三次,執行三次,就會更新三次
所以尤大想到了一個方法,就是在事件回調執行時,注冊的是宏任務
宏任務并不會在事件結束之后馬上調用
只會在連續事件結束之后,才調用,這就是我們想要的
所以你才能看到 使用 useMacroTask 來控制注冊的任務類型
現在我把上面的例子中的 promise 換成 setTimeout,重新點擊一下
但是!!在 【Vue 2.6】 中,我們已經看不到 useMacroTask 的身影了,為什么?
因為 Vue 又全部使用微任務了........ 天道輪回.....
(其實并不是全部是微任務,兼容寫法最后是 setTimeout)
你問,那冒泡又怎么辦?好吧,尤大想到了另一個辦法來解決冒泡的問題
就是判斷當時的 事件 target,來判斷是否執行事件回調
也就間接解決了這個問題,看看新的綁定事件的源碼
function add$1(name, handler) { handler = function(e) { if ( e.target === e.currentTarget || e.target.ownerDocument !== document ) { return handler.apply(this, arguments) } }; target$1.addEventListener(name, handler); }
通過判斷 target 就解決了冒泡,但是這樣就不能用冒泡了好像??
也不知道有沒有什么壞處,如果有的話,后面尤大肯定會更新的
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/110258.html
摘要:盡量把所有異步代碼放在一個宏微任務中,減少消耗加快異步代碼的執行。我們知道,如果一個異步代碼就注冊一個宏微任務的話,那么執行完全部異步代碼肯定慢很多避免頻繁地更新。中就算我們一次性修改多次數據,頁面還是只會更新一次。 寫文章不容易,點個贊唄兄弟專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內部詳情,讓我們一起學習吧研究基于 Vue版本 【2.5...
寫文章不容易,點個贊唄兄弟專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內部詳情,讓我們一起學習吧研究基于 Vue版本 【2.5.17】 如果你覺得排版難看,請點擊 下面鏈接 或者 拉到 下面關注公眾號也可以吧 【Vue原理】NextTick - 源碼版 之 服務Vue 初次看的兄弟可以先看 【Vue原理】NextTick - 白話版 簡單了解下...
摘要:通常會做很多判斷來選擇存在的類型,比如判斷等是否存在,而選擇他為微任務類型但是可能宏微任務最后都是,因為他是保守兼容處理。 寫文章不容易,點個贊唄兄弟專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內部詳情,讓我們一起學習吧研究基于 Vue版本 【2.5.17】 如果你覺得排版難看,請點擊 下面鏈接 或者 拉到 下面關注公眾號也可以吧 【V...
摘要:寫文章不容易,點個贊唄兄弟專注源碼分享,文章分為白話版和源碼版,白話版助于理解工作原理,源碼版助于了解內部詳情,讓我們一起學習吧研究基于版本如果你覺得排版難看,請點擊下面鏈接或者拉到下面關注公眾號也可以吧原理源碼版之綁定標簽事件這里的綁定 寫文章不容易,點個贊唄兄弟專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內部詳情,讓我們一起學習吧研究基于...
摘要:哪吒別人的看法都是狗屁,你是誰只有你自己說了才算,這是爹教我的道理。哪吒去他個鳥命我命由我,不由天是魔是仙,我自己決定哪吒白白搭上一條人命,你傻不傻敖丙不傻誰和你做朋友太乙真人人是否能夠改變命運,我不曉得。我只曉得,不認命是哪吒的命。 showImg(https://segmentfault.com/img/bVbwiGL?w=900&h=378); 出處 查看github最新的Vue...
閱讀 2600·2023-04-25 20:50
閱讀 3964·2023-04-25 18:45
閱讀 2233·2021-11-17 17:00
閱讀 3338·2021-10-08 10:05
閱讀 3087·2019-08-30 15:55
閱讀 3505·2019-08-30 15:44
閱讀 2366·2019-08-29 13:51
閱讀 1123·2019-08-29 12:47