<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
        主站蜘蛛池模板: 日韩一区二区在线免费观看| 真实国产乱子伦精品免费| www亚洲精品久久久乳| 美国免费高清一级毛片| 久久精品国产影库免费看| 国产a视频精品免费观看| 成年女人午夜毛片免费视频| 国产成人在线观看免费网站| 亚洲乳大丰满中文字幕| 亚洲ts人妖网站| 国产亚洲情侣久久精品| 国产无遮挡吃胸膜奶免费看视频 | 亚洲Av无码国产一区二区| japanese色国产在线看免费| 24小时日本韩国高清免费| 国产精品亚洲w码日韩中文| 亚洲欧洲日产国码二区首页 | 一级毛片一级毛片免费毛片| 91在线手机精品免费观看| 亚洲网站在线免费观看| 国产精品高清免费网站| 亚洲爆乳无码专区| 国产成人亚洲精品播放器下载| 免费人成年激情视频在线观看| 亚洲妇女无套内射精| 最近在线2018视频免费观看| 亚洲日本成本人观看| 波多野结衣免费在线观看| 亚洲av中文无码乱人伦在线播放| 国产精品亚洲lv粉色| 国精无码欧精品亚洲一区| 国产精品免费久久久久电影网| 久久久久亚洲AV无码永不| 久久久久久毛片免费看| 无码专区一va亚洲v专区在线 | 四虎影库久免费视频| 亚洲精品国产av成拍色拍| 亚洲熟女少妇一区二区| 成年在线观看网站免费| 亚洲精品视频在线观看免费| 日本免费人成黄页在线观看视频|