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