亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專(zhuān)欄INFORMATION COLUMN

【Vue原理】NextTick - 源碼版 之 獨(dú)立自身

劉東 / 1193人閱讀

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

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

如果你覺(jué)得排版難看,請(qǐng)點(diǎn)擊 下面鏈接 或者 拉到 下面關(guān)注公眾號(hào)也可以吧

【Vue原理】NextTick - 源碼版 之 獨(dú)立自身

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

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

nextTick 是一個(gè)在 Vue 中比較獨(dú)立的東西,可以直接拿出來(lái)為你的項(xiàng)目服務(wù)

nextTick 涉及的點(diǎn),就下面這些

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

沒(méi)看懂?沒(méi)關(guān)系,后面會(huì)慢慢說(shuō)

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

接下來(lái)就是一個(gè)個(gè)去詳細(xì)記錄了

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

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

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

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

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

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

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

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

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

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

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

假設(shè)現(xiàn)在正在執(zhí)行第一個(gè)宏任務(wù) setTimeout,執(zhí)行完之后,會(huì)開(kāi)始清空?qǐng)?zhí)行 微任務(wù)隊(duì)列

于是開(kāi)始執(zhí)行了兩個(gè)Promise

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

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

常見(jiàn)宏任務(wù)

setTimeout

setInterval

setImmediate

script

MessageChannel

常見(jiàn)微任務(wù)

Promise

MutationObserver

Object.observe(廢棄)

process.nextTick(node)

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

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

在這里先埋下兩個(gè)問(wèn)題

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

這兩個(gè)問(wèn)題會(huì)記錄在另外一篇文章

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

以適用于不同的場(chǎng)景,下面就是這兩個(gè)函數(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);
    };
}

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

MessageChannel

簡(jiǎn)單來(lái)說(shuō),MessageChannel 用于創(chuàng)建了一個(gè)通信的管道,這個(gè)管道有兩個(gè)端口

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

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

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

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

    varp =Promise.resolve();

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

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

Vue 的任務(wù)隊(duì)列

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

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

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

3、避免頻繁地更新。Vue 中就算我們一次性修改多次數(shù)據(jù),頁(yè)面還是只會(huì)更新一次。就是因?yàn)檫@樣,避免多次修改數(shù)據(jù)導(dǎo)致的多次頻繁更新頁(yè)面,讓多次修改只用更新最后一次

下面就來(lái)說(shuō)一下Vue 相關(guān)的實(shí)現(xiàn)

1、callbacks

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

this.$nextTick(()=>{    

    console.log(1111)

})

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

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

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

沒(méi)錯(cuò),這個(gè)方法就是 flushCallbacks

2、flushCallbacks

方法灰常簡(jiǎn)單啊,大家肯定能看得懂啊

1、復(fù)制一遍 callbacks

2、把 原來(lái) callbacks 清空

3、遍歷 復(fù)制的 callbacks ,然后逐個(gè)執(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]();
    }
}

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

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

setTimeout(flushCallbacks)

嘿,我們之前有講過(guò),Vue 會(huì)控制當(dāng)時(shí)執(zhí)行棧的所有異步代碼只注冊(cè)一個(gè) 宏微任務(wù)

那么是怎么控制的呢?

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

下面就需要請(qǐng)出我們的豬腳,nextTick 函數(shù)閃亮登場(chǎng)!?。?/p>

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

通過(guò)判斷 pending 來(lái)確定是否需要注冊(cè)宏微任務(wù)

當(dāng)?shù)谝淮巫?cè)的時(shí)候,把 pending 設(shè)置為 true,表示任務(wù)隊(duì)列已經(jīng)在開(kāi)始了,同一時(shí)期內(nèi)無(wú)需注冊(cè)了

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

2、callbacks

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

3、useMacroTask

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

沒(méi)錯(cuò),就是這個(gè)鬼東西了,設(shè)置為 true 時(shí)注冊(cè)宏任務(wù),設(shè)置為false 注冊(cè)微任務(wù)

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

這個(gè)東西,在哪里用過(guò)啊?

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

你問(wèn)為什么??jī)?nèi)容太多,會(huì)有專(zhuān)篇分析

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

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/110260.html

相關(guān)文章

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

    寫(xiě)文章不容易,點(diǎn)個(gè)贊唄兄弟專(zhuān)注 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)單了解下...

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

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

    raise_yang 評(píng)論0 收藏0
  • Vue原理NextTick - 白話

    摘要:通常會(huì)做很多判斷來(lái)選擇存在的類(lèi)型,比如判斷等是否存在,而選擇他為微任務(wù)類(lèi)型但是可能宏微任務(wù)最后都是,因?yàn)樗潜J丶嫒萏幚怼? 寫(xiě)文章不容易,點(diǎn)個(gè)贊唄兄弟專(zhuān)注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于 Vue版本 【2.5.17】 如果你覺(jué)得排版難看,請(qǐng)點(diǎn)擊 下面鏈接 或者 拉到 下面關(guān)注公眾號(hào)也可以吧 【V...

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

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

    ccj659 評(píng)論0 收藏0
  • 前方來(lái)報(bào),八月最新資訊--關(guān)于vue2&3的最佳文章推薦

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

    izhuhaodev 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<