成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

【Vue原理】NextTick - 源碼版 之 獨立自身

劉東 / 1146人閱讀

摘要:盡量把所有異步代碼放在一個宏微任務(wù)中,減少消耗加快異步代碼的執(zhí)行。我們知道,如果一個異步代碼就注冊一個宏微任務(wù)的話,那么執(zhí)行完全部異步代碼肯定慢很多避免頻繁地更新。中就算我們一次性修改多次數(shù)據(jù),頁面還是只會更新一次。

寫文章不容易,點個贊唄兄弟
專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學習吧
研究基于 Vue版本 【2.5.17】

如果你覺得排版難看,請點擊 下面鏈接 或者 拉到 下面關(guān)注公眾號也可以吧

【Vue原理】NextTick - 源碼版 之 獨立自身

好的,今天到了 nextTick 的環(huán)節(jié),之前我看的版本是 2.5.17,然后瞄了一眼 2.6 的,發(fā)現(xiàn)對于 nextTick 修改了 少部分內(nèi)容,但是不太大,所以就一起記錄下來

(如果改太多,就懶得看了.....反正了解一個思想以及實現(xiàn)思路就行了)

nextTick 是一個在 Vue 中比較獨立的東西,可以直接拿出來為你的項目服務(wù)

nextTick 涉及的點,就下面這些

1、任務(wù)隊列callbacks
2、任務(wù)隊列執(zhí)行函數(shù) flushCallbacks
3、控制(宏任務(wù),微任務(wù))注冊標志位 pending
4、宏任務(wù),微任務(wù)

沒看懂?沒關(guān)系,后面會慢慢說

這篇先講 nextTick 自身,下篇再講 nextTick 和 Vue 的關(guān)聯(lián)

接下來就是一個個去詳細記錄了

宏任務(wù),微任務(wù)

這個知識點,很重要,也不算太簡單,在網(wǎng)上也能找到很多很好的講解,比如下面這篇文章,在這里不會特別解釋這兩個,畢竟主題不是這個

https://juejin.im/post/59e85e...

宏微任務(wù)的下面總結(jié)也是個人理解,有錯盡管罵我

那么這里就先記錄一下相關(guān)的結(jié)論

1、宏任務(wù)和微任務(wù)都是異步
2、宏任務(wù)和微任務(wù)會被注冊到兩個不同的隊列中
3、宏任務(wù)隊列不是一次性清空執(zhí)行,而是執(zhí)行一個宏任務(wù)時,
然后去清空執(zhí)行一列微任務(wù)隊列

接著再執(zhí)行下一個宏任務(wù).....循環(huán)往復,直到所有隊列都為空

什么是一個宏任務(wù)

比如 一個 setTimeout 就是一個宏任務(wù),兩個 setTimeout 就是兩個宏任務(wù)

例子說明執(zhí)行順序

比如現(xiàn)在,宏任務(wù)隊列中有兩個 setTimeout,微任務(wù)隊列中有兩個 Promise

假設(shè)現(xiàn)在正在執(zhí)行第一個宏任務(wù) setTimeout,執(zhí)行完之后,會開始清空執(zhí)行 微任務(wù)隊列

于是開始執(zhí)行了兩個Promise

結(jié)束之后,接著執(zhí)行 另一個宏任務(wù), setTimeout

以前我以為是 宏任務(wù)隊列執(zhí)行完,再執(zhí)行微任務(wù)隊列,發(fā)現(xiàn)不是,很受傷,都是了解 nextTick 源碼讓我有機會重新了解了一遍 這個知識點

常見宏任務(wù)

setTimeout

setInterval

setImmediate

script

MessageChannel

常見微任務(wù)

Promise

MutationObserver

Object.observe(廢棄)

process.nextTick(node)

Vue 中的宏任務(wù) 和 微任務(wù) 源碼

以下談的是 版本 2.5.17 的,在 2.6 中,去掉宏任務(wù)了

在這里先埋下兩個問題

1、Vue為什么需要宏任務(wù)和 微任務(wù)
2、Vue在哪里使用到了宏任務(wù)和微任務(wù)

這兩個問題會記錄在另外一篇文章

Vue 中有兩個函數(shù),macroTimerFunc 用于注冊宏任務(wù),microTimerFunc 用于注冊微任務(wù)

以適用于不同的場景,下面就是這兩個函數(shù)的源碼

1、macroTimerFunc
if(如果setImmediate存在) {
    macroTimerFunc =function(){
        setImmediate(flushCallbacks);
    };

}

elseif(如果MessageChannel存在) {    

   varchannel =newMessageChannel();    

    varport = channel.port2;

   channel.port1.onmessage = flushCallbacks;
    macroTimerFunc =function(){
        port.postMessage(1);
    };

}

else{

   macroTimerFunc =function(){
        setTimeout(flushCallbacks,0);
    };
}

沒啥好說的,最多記錄一下 MessageChannel,更多內(nèi)容就自己查啦

MessageChannel

簡單來說,MessageChannel 用于創(chuàng)建了一個通信的管道,這個管道有兩個端口

每個端口都可以通過postMessage發(fā)送數(shù)據(jù)

一個端口綁定onmessage回調(diào),從另一個端口接收傳過來的數(shù)據(jù)

不多說了,看下一個微任務(wù)

2、microTimerFunc
if(如果promise存在) {    

    varp =Promise.resolve();

   microTimerFunc =function(){
        p.then(flushCallbacks);
    };
}else{
    microTimerFunc = macroTimerFunc;
}

上面的宏微任務(wù) 函數(shù)都 出現(xiàn)了一個 flushCallbacks 的東西,下面會有

Vue 的任務(wù)隊列

vue 自己維護了一個任務(wù)隊列去配合 宏微任務(wù)使用,目的無非是幾樣

1、減少宏微任務(wù)的注冊。盡量把所有異步代碼放在一個 宏微任務(wù)中,減少消耗

2、加快異步代碼的執(zhí)行。我們知道,如果一個異步代碼就注冊一個宏微任務(wù)的話,那么執(zhí)行完全部異步代碼肯定慢很多

3、避免頻繁地更新。Vue 中就算我們一次性修改多次數(shù)據(jù),頁面還是只會更新一次。就是因為這樣,避免多次修改數(shù)據(jù)導致的多次頻繁更新頁面,讓多次修改只用更新最后一次

下面就來說一下Vue 相關(guān)的實現(xiàn)

1、callbacks

callbacks 是一個數(shù)組,用于存放各種異步函數(shù)。比如

this.$nextTick(()=>{    

    console.log(1111)

})

就會把你設(shè)置的這個回調(diào),放到 callbacks 數(shù)組中

callbacks.push(()=>{    
    console.log(1111)
})

既然 callbacks 是存放異步回調(diào)的,那么肯定有一個方法,是遍歷 callbacks ,然后逐個執(zhí)行其中存放的函數(shù)

沒錯,這個方法就是 flushCallbacks

2、flushCallbacks

方法灰常簡單啊,大家肯定能看得懂啊

1、復制一遍 callbacks

2、把 原來 callbacks 清空

3、遍歷 復制的 callbacks ,然后逐個執(zhí)行

var callbacks = [];

var pending =false;


functionflushCallbacks(){

   pending =false;    

    varcopies = callbacks.slice(0);

   callbacks.length =0;    

    for(vari =0; i < copies.length; i++) {

       copies[i]();
    }
}

這個方法是 直接傳給 上面設(shè)置的 宏任務(wù)函數(shù) 和 微任務(wù)函數(shù)的額

也就是說,宏任務(wù)和 微任務(wù) 的回調(diào),都是執(zhí)行這個 flushCallbacks

setTimeout(flushCallbacks)

嘿,我們之前有講過,Vue 會控制當時執(zhí)行棧的所有異步代碼只注冊一個 宏微任務(wù)

那么是怎么控制的呢?

還有還有,是怎么把 異步函數(shù) 存放到 callbacks 中的呢?

下面就需要請出我們的豬腳,nextTick 函數(shù)閃亮登場?。?!

3、NextTick
Vue.nextTick =function(cb, ctx){

    callbacks.push(function(){
        cb && cb.call(ctx);
   });    

    if(!pending) {

       pending =true;        

        if(useMacroTask) {

           macroTimerFunc();
        }else{
            microTimerFunc();
        }
    }
}
1、pending

通過判斷 pending 來確定是否需要注冊宏微任務(wù)

當?shù)谝淮巫缘臅r候,把 pending 設(shè)置為 true,表示任務(wù)隊列已經(jīng)在開始了,同一時期內(nèi)無需注冊了

然后在 任務(wù)隊列 執(zhí)行完畢之后,再把 pending 設(shè)置為 false(在 flushCallbacks 中)

2、callbacks

你可以看到,就是在這里進行存放 異步函數(shù),還特地【包裝】了一遍,為了綁定一個上下文對象

3、useMacroTask

Vue 怎么控制注冊宏任務(wù)還是微任務(wù)呢?

沒錯,就是這個鬼東西了,設(shè)置為 true 時注冊宏任務(wù),設(shè)置為false 注冊微任務(wù)

“在 2.6 版本中,已經(jīng)不存在這個鬼東西,全部使用了微任務(wù)注冊”

這個東西,在哪里用過???

在 注冊 DOM 事件的時候用到,當事件回調(diào)執(zhí)行的過程中,所有的異步代碼都使用宏任務(wù)

你問為什么?內(nèi)容太多,會有專篇分析

然后,關(guān)于 macroTimerFunc 和 microTimerFunc 上文已經(jīng)講過啦,可以回去看看

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/110260.html

相關(guān)文章

  • Vue原理NextTick - 源碼 服務(wù)Vue

    寫文章不容易,點個贊唄兄弟專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學習吧研究基于 Vue版本 【2.5.17】 如果你覺得排版難看,請點擊 下面鏈接 或者 拉到 下面關(guān)注公眾號也可以吧 【Vue原理】NextTick - 源碼版 之 服務(wù)Vue 初次看的兄弟可以先看 【Vue原理】NextTick - 白話版 簡單了解下...

    Acceml 評論0 收藏0
  • Vue原理NextTick - 源碼 宏微任務(wù)的抉擇

    摘要:這么講,有點籠統(tǒng),準確地說,應(yīng)該是事件回調(diào)執(zhí)行過程中,在主線程為空之后,異步代碼執(zhí)行之前,所有通過注冊的異步代碼都是用宏任務(wù)。 寫文章不容易,點個贊唄兄弟專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學習吧研究基于 Vue版本 【2.5.17】 如果你覺得排版難看,請點擊 下面鏈接 或者 拉到 下面關(guān)注公眾號也可以吧 【...

    raise_yang 評論0 收藏0
  • Vue原理NextTick - 白話

    摘要:通常會做很多判斷來選擇存在的類型,比如判斷等是否存在,而選擇他為微任務(wù)類型但是可能宏微任務(wù)最后都是,因為他是保守兼容處理。 寫文章不容易,點個贊唄兄弟專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學習吧研究基于 Vue版本 【2.5.17】 如果你覺得排版難看,請點擊 下面鏈接 或者 拉到 下面關(guān)注公眾號也可以吧 【V...

    zeyu 評論0 收藏0
  • 阿里校招前端面經(jīng)

    摘要:的回調(diào)函數(shù)執(zhí)行的優(yōu)先級要高于,屬于觀察者。的回調(diào)函數(shù)保存在一個數(shù)組中,會將異步回調(diào)放到當前幀的末尾回調(diào)之前,如果過多,會導致回調(diào)不斷延后最后堆積太多。 阿里一面是電話面,問得不多,但是挺有深度。面試官一開始就說,看了你的項目,覺得你基礎(chǔ)挺好的,那我就不問基礎(chǔ)了。然后全程就真的沒有問一個基礎(chǔ)問題。。 1.說說你做的那個網(wǎng)頁版手機QQ項目的難點。 我首先想到了滾動條位置無法還原的問題,也就...

    ccj659 評論0 收藏0
  • 前方來報,八月最新資訊--關(guān)于vue2&3的最佳文章推薦

    摘要:哪吒別人的看法都是狗屁,你是誰只有你自己說了才算,這是爹教我的道理。哪吒去他個鳥命我命由我,不由天是魔是仙,我自己決定哪吒白白搭上一條人命,你傻不傻敖丙不傻誰和你做朋友太乙真人人是否能夠改變命運,我不曉得。我只曉得,不認命是哪吒的命。 showImg(https://segmentfault.com/img/bVbwiGL?w=900&h=378); 出處 查看github最新的Vue...

    izhuhaodev 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<