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