摘要:這么講,有點籠統(tǒng),準確地說,應(yīng)該是事件回調(diào)執(zhí)行過程中,在主線程為空之后,異步代碼執(zhí)行之前,所有通過注冊的異步代碼都是用宏任務(wù)。
寫文章不容易,點個贊唄兄弟
專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧
研究基于 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ù)就是解決這兩個問題!!!
在這里,大家肯定必須一定要了解了 宏任務(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,重新點擊一下
但是!!在 【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://specialneedsforspecialkids.com/yun/110258.html
摘要:盡量把所有異步代碼放在一個宏微任務(wù)中,減少消耗加快異步代碼的執(zhí)行。我們知道,如果一個異步代碼就注冊一個宏微任務(wù)的話,那么執(zhí)行完全部異步代碼肯定慢很多避免頻繁地更新。中就算我們一次性修改多次數(shù)據(jù),頁面還是只會更新一次。 寫文章不容易,點個贊唄兄弟專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于 Vue版本 【2.5...
寫文章不容易,點個贊唄兄弟專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于 Vue版本 【2.5.17】 如果你覺得排版難看,請點擊 下面鏈接 或者 拉到 下面關(guān)注公眾號也可以吧 【Vue原理】NextTick - 源碼版 之 服務(wù)Vue 初次看的兄弟可以先看 【Vue原理】NextTick - 白話版 簡單了解下...
摘要:通常會做很多判斷來選擇存在的類型,比如判斷等是否存在,而選擇他為微任務(wù)類型但是可能宏微任務(wù)最后都是,因為他是保守兼容處理。 寫文章不容易,點個贊唄兄弟專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于 Vue版本 【2.5.17】 如果你覺得排版難看,請點擊 下面鏈接 或者 拉到 下面關(guān)注公眾號也可以吧 【V...
摘要:寫文章不容易,點個贊唄兄弟專注源碼分享,文章分為白話版和源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于版本如果你覺得排版難看,請點擊下面鏈接或者拉到下面關(guān)注公眾號也可以吧原理源碼版之綁定標簽事件這里的綁定 寫文章不容易,點個贊唄兄弟專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于...
摘要:哪吒別人的看法都是狗屁,你是誰只有你自己說了才算,這是爹教我的道理。哪吒去他個鳥命我命由我,不由天是魔是仙,我自己決定哪吒白白搭上一條人命,你傻不傻敖丙不傻誰和你做朋友太乙真人人是否能夠改變命運,我不曉得。我只曉得,不認命是哪吒的命。 showImg(https://segmentfault.com/img/bVbwiGL?w=900&h=378); 出處 查看github最新的Vue...
閱讀 2593·2023-04-25 20:50
閱讀 3946·2023-04-25 18:45
閱讀 2220·2021-11-17 17:00
閱讀 3330·2021-10-08 10:05
閱讀 3080·2019-08-30 15:55
閱讀 3495·2019-08-30 15:44
閱讀 2360·2019-08-29 13:51
閱讀 1118·2019-08-29 12:47