<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關(guān)鍵字專題1關(guān)鍵字專題50關(guān)鍵字專題500關(guān)鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關(guān)鍵字專題關(guān)鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
        當(dāng)前位置: 首頁 - 科技 - 知識百科 - 正文

        Vue源碼中批量異步更新與nextTick原理的解析

        來源:懂視網(wǎng) 責(zé)編:小采 時間:2020-11-27 19:33:21
        文檔

        Vue源碼中批量異步更新與nextTick原理的解析

        Vue源碼中批量異步更新與nextTick原理的解析:這篇文章給大家介紹的內(nèi)容是關(guān)于Vue源碼中批量異步更新與nextTick原理的解析,有著一定的參考價值,有需要的朋友可以參考一下。vue已是目前國內(nèi)前端web端三分天下之一,同時也作為本人主要技術(shù)棧之一,在日常使用中知其然也好奇著所以然,另外最近的社區(qū)涌現(xiàn)
        推薦度:
        導(dǎo)讀Vue源碼中批量異步更新與nextTick原理的解析:這篇文章給大家介紹的內(nèi)容是關(guān)于Vue源碼中批量異步更新與nextTick原理的解析,有著一定的參考價值,有需要的朋友可以參考一下。vue已是目前國內(nèi)前端web端三分天下之一,同時也作為本人主要技術(shù)棧之一,在日常使用中知其然也好奇著所以然,另外最近的社區(qū)涌現(xiàn)

        為什么默認優(yōu)先使用 micro task 呢,是利用其高優(yōu)先級的特性,保證隊列中的微任務(wù)在一次循環(huán)全部執(zhí)行完畢。

        強制 macro task 的方法是在綁定 DOM 事件的時候,默認會給回調(diào)的 handler 函數(shù)調(diào)用 withMacroTask 方法做一層包裝 handler = withMacroTask(handler),它保證整個回調(diào)函數(shù)執(zhí)行過程中,遇到數(shù)據(jù)狀態(tài)的改變,這些改變都會被推到 macro task 中。以上實現(xiàn)在 src/platforms/web/runtime/modules/events.js 的 add 方法中,可以自己看一看具體代碼。

        剛好在寫這篇文章的時候思否上有人問了個問題 vue 2.4 和2.5 版本的@input事件不一樣 ,這個問題的原因也是因為2.5之前版本的DOM事件采用 micro task ,而之后采用 macro task,解決的途徑參考 < Vue.js 升級踩坑小記> 中介紹的幾個辦法,這里就提供一個在mounted鉤子中用 addEventListener 添加原生事件的方法來實現(xiàn),參見 CodePen。

        3. 一個例子

        說這么多,不如來個例子,執(zhí)行參見 CodePen

        <p id="app">
         <span id='name' ref='name'>{{ name }}</span>
         <button @click='change'>change name</button>
         <p id='content'></p>
        </p>
        <script>
         new Vue({
         el: '#app',
         data() {
         return {
         name: 'SHERlocked93'
         }
         },
         methods: {
         change() {
         const $name = this.$refs.name
         this.$nextTick(() => console.log('setter前:' + $name.innerHTML))
         this.name = ' name改嘍 '
         console.log('同步方式:' + this.$refs.name.innerHTML)
         setTimeout(() => this.console("setTimeout方式:" + this.$refs.name.innerHTML))
         this.$nextTick(() => console.log('setter后:' + $name.innerHTML))
         this.$nextTick().then(() => console.log('Promise方式:' + $name.innerHTML))
         }
         }
         })
        </script>

        執(zhí)行以下看看結(jié)果:

        同步方式:SHERlocked93 
        setter前:SHERlocked93 
        setter后:name改嘍 
        Promise方式:name改嘍 
        setTimeout方式:name改嘍

        為什么是這樣的結(jié)果呢,解釋一下:

        1. 同步方式: 當(dāng)把data中的name修改之后,此時會觸發(fā)name的 setter 中的 dep.notify 通知依賴本data的render watcher去 updateupdate 會把 flushSchedulerQueue 函數(shù)傳遞給 nextTick,render watcher在 flushSchedulerQueue 函數(shù)運行時 watcher.run 再走 diff -> patch 那一套重渲染 re-render 視圖,這個過程中會重新依賴收集,這個過程是異步的;所以當(dāng)我們直接修改了name之后打印,這時異步的改動還沒有被 patch 到視圖上,所以獲取視圖上的DOM元素還是原來的內(nèi)容。

        2. setter前: setter前為什么還打印原來的是原來內(nèi)容呢,是因為 nextTick 在被調(diào)用的時候把回調(diào)挨個push進callbacks數(shù)組,之后執(zhí)行的時候也是 for 循環(huán)出來挨個執(zhí)行,所以是類似于隊列這樣一個概念,先入先出;在修改name之后,觸發(fā)把render watcher填入 schedulerQueue 隊列并把他的執(zhí)行函數(shù) flushSchedulerQueue 傳遞給 nextTick ,此時callbacks隊列中已經(jīng)有了 setter前函數(shù) 了,因為這個 cb 是在 setter前函數(shù) 之后被push進callbacks隊列的,那么先入先出的執(zhí)行callbacks中回調(diào)的時候先執(zhí)行 setter前函數(shù),這時并未執(zhí)行render watcher的 watcher.run,所以打印DOM元素仍然是原來的內(nèi)容。

        3. setter后: setter后這時已經(jīng)執(zhí)行完 flushSchedulerQueue,這時render watcher已經(jīng)把改動 patch 到視圖上,所以此時獲取DOM是改過之后的內(nèi)容。

        4. Promise方式: 相當(dāng)于 Promise.then 的方式執(zhí)行這個函數(shù),此時DOM已經(jīng)更改。

        5. setTimeout方式: 最后執(zhí)行macro task的任務(wù),此時DOM已經(jīng)更改。

        注意,在執(zhí)行 setter前函數(shù) 這個異步任務(wù)之前,同步的代碼已經(jīng)執(zhí)行完畢,異步的任務(wù)都還未執(zhí)行,所有的 $nextTick 函數(shù)也執(zhí)行完畢,所有回調(diào)都被push進了callbacks隊列中等待執(zhí)行,所以在setter前函數(shù) 執(zhí)行的時候,此時callbacks隊列是這樣的:[setter前函數(shù)flushSchedulerQueuesetter后函數(shù)Promise方式函數(shù)],它是一個micro task隊列,執(zhí)行完畢之后執(zhí)行macro task setTimeout,所以打印出上面的結(jié)果。

        另外,如果瀏覽器的宏任務(wù)隊列里面有setImmediateMessageChannelsetTimeout/setInterval 各種類型的任務(wù),那么會按照上面的順序挨個按照添加進event loop中的順序執(zhí)行,所以如果瀏覽器支持MessageChannelnextTick 執(zhí)行的是 macroTimerFunc,那么如果 macrotask queue 中同時有 nextTick 添加的任務(wù)和用戶自己添加的 setTimeout 類型的任務(wù),會優(yōu)先執(zhí)行 nextTick 中的任務(wù),因為MessageChannel 的優(yōu)先級比 setTimeout的高,setImmediate 同理。

        聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        Vue源碼中批量異步更新與nextTick原理的解析

        Vue源碼中批量異步更新與nextTick原理的解析:這篇文章給大家介紹的內(nèi)容是關(guān)于Vue源碼中批量異步更新與nextTick原理的解析,有著一定的參考價值,有需要的朋友可以參考一下。vue已是目前國內(nèi)前端web端三分天下之一,同時也作為本人主要技術(shù)棧之一,在日常使用中知其然也好奇著所以然,另外最近的社區(qū)涌現(xiàn)
        推薦度:
        標(biāo)簽: 原理 VUE 解析
        • 熱門焦點

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 亚洲国产精品狼友中文久久久| 真人做A免费观看| 午夜无遮挡羞羞漫画免费| 亚洲精品成人网站在线播放| 日韩精品无码一区二区三区免费 | 日本三级2019在线观看免费| 亚洲狠狠狠一区二区三区| 999国内精品永久免费观看| 亚洲成a人片在线不卡| 在线观看免费毛片| 国产精品手机在线亚洲| 亚洲人成电影网站国产精品| 成人av片无码免费天天看| 精品亚洲综合在线第一区| 精品免费人成视频app| 亚洲偷自拍另类图片二区| 国产精品成人四虎免费视频| 鲁啊鲁在线视频免费播放| 国产亚洲AV手机在线观看| 免费h视频在线观看| 亚洲国产综合第一精品小说| 成**人免费一级毛片| 一级毛片免费毛片毛片| 午夜亚洲AV日韩AV无码大全| 亚洲精品视频免费在线观看| 亚洲av综合av一区二区三区| 亚洲无av在线中文字幕| 免费福利网站在线观看| 边摸边吃奶边做爽免费视频99| 亚洲成AV人片在线观看无| 成年女人免费v片| h视频在线观看免费| 亚洲国产成AV人天堂无码| 亚洲不卡无码av中文字幕| 在线看片免费人成视频久网下载| 亚洲无圣光一区二区| 亚洲а∨天堂久久精品| 亚洲一区二区免费视频| 色www免费视频| 亚洲人成综合在线播放| 亚洲伊人久久成综合人影院|