国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

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

劉東 / 1144人閱讀

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

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

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

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

好的,今天到了 nextTick 的環節,之前我看的版本是 2.5.17,然后瞄了一眼 2.6 的,發現對于 nextTick 修改了 少部分內容,但是不太大,所以就一起記錄下來

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

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

nextTick 涉及的點,就下面這些

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

沒看懂?沒關系,后面會慢慢說

這篇先講 nextTick 自身,下篇再講 nextTick 和 Vue 的關聯

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

宏任務,微任務

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

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

宏微任務的下面總結也是個人理解,有錯盡管罵我

那么這里就先記錄一下相關的結論

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

接著再執行下一個宏任務.....循環往復,直到所有隊列都為空

什么是一個宏任務

比如 一個 setTimeout 就是一個宏任務,兩個 setTimeout 就是兩個宏任務

例子說明執行順序

比如現在,宏任務隊列中有兩個 setTimeout,微任務隊列中有兩個 Promise

假設現在正在執行第一個宏任務 setTimeout,執行完之后,會開始清空執行 微任務隊列

于是開始執行了兩個Promise

結束之后,接著執行 另一個宏任務, setTimeout

以前我以為是 宏任務隊列執行完,再執行微任務隊列,發現不是,很受傷,都是了解 nextTick 源碼讓我有機會重新了解了一遍 這個知識點

常見宏任務

setTimeout

setInterval

setImmediate

script

MessageChannel

常見微任務

Promise

MutationObserver

Object.observe(廢棄)

process.nextTick(node)

Vue 中的宏任務 和 微任務 源碼

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

在這里先埋下兩個問題

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

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

Vue 中有兩個函數,macroTimerFunc 用于注冊宏任務,microTimerFunc 用于注冊微任務

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

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,更多內容就自己查啦

MessageChannel

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

每個端口都可以通過postMessage發送數據

一個端口綁定onmessage回調,從另一個端口接收傳過來的數據

不多說了,看下一個微任務

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

    varp =Promise.resolve();

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

上面的宏微任務 函數都 出現了一個 flushCallbacks 的東西,下面會有

Vue 的任務隊列

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

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

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

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

下面就來說一下Vue 相關的實現

1、callbacks

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

this.$nextTick(()=>{    

    console.log(1111)

})

就會把你設置的這個回調,放到 callbacks 數組中

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

既然 callbacks 是存放異步回調的,那么肯定有一個方法,是遍歷 callbacks ,然后逐個執行其中存放的函數

沒錯,這個方法就是 flushCallbacks

2、flushCallbacks

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

1、復制一遍 callbacks

2、把 原來 callbacks 清空

3、遍歷 復制的 callbacks ,然后逐個執行

var callbacks = [];

var pending =false;


functionflushCallbacks(){

   pending =false;    

    varcopies = callbacks.slice(0);

   callbacks.length =0;    

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

       copies[i]();
    }
}

這個方法是 直接傳給 上面設置的 宏任務函數 和 微任務函數的額

也就是說,宏任務和 微任務 的回調,都是執行這個 flushCallbacks

setTimeout(flushCallbacks)

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

那么是怎么控制的呢?

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

下面就需要請出我們的豬腳,nextTick 函數閃亮登場!!!

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 來確定是否需要注冊宏微任務

當第一次注冊的時候,把 pending 設置為 true,表示任務隊列已經在開始了,同一時期內無需注冊了

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

2、callbacks

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

3、useMacroTask

Vue 怎么控制注冊宏任務還是微任務呢?

沒錯,就是這個鬼東西了,設置為 true 時注冊宏任務,設置為false 注冊微任務

“在 2.6 版本中,已經不存在這個鬼東西,全部使用了微任務注冊”

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

在 注冊 DOM 事件的時候用到,當事件回調執行的過程中,所有的異步代碼都使用宏任務

你問為什么?內容太多,會有專篇分析

然后,關于 macroTimerFunc 和 microTimerFunc 上文已經講過啦,可以回去看看

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/110260.html

相關文章

  • Vue原理NextTick - 源碼 服務Vue

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

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

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

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

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

    zeyu 評論0 收藏0
  • 阿里校招前端面經

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

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

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

    izhuhaodev 評論0 收藏0

發表評論

0條評論

劉東

|高級講師

TA的文章

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