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

資訊專欄INFORMATION COLUMN

event loop 與 vue

springDevBird / 1067人閱讀

摘要:但是導致了很明顯的性能問題。上述兩個例子其實是在這個中找到的,第一個使用的版本是,這個版本的實現(xiàn)是采用了,而后因為的里的有,于是尤雨溪更改了實現(xiàn),換成了,也就是后一個所使用的。后來尤雨溪了解到是將回調放入的隊列。

結論

對于event loop 可以抽象成一段簡單的代碼表示

for (macroTask of macroTaskQueue) {
    // 1. Handle current MACRO-TASK
    handleMacroTask();
      
    // 2. Handle all MICRO-TASK
    for (microTask of microTaskQueue) {
        handleMicroTask(microTask);
    }
}
js事件機制

javascript是一個單線程語言,同一時間只能執(zhí)行一個任務。
對于javascript的事件處理機制,我們可以簡單理解成“主線程+任務隊列”模式。主要步驟如下

(1)所有同步任務都在主線程上執(zhí)行,形成一個執(zhí)行棧。

(2)主線程之外,還存在一個 "任務隊列"(task queue)。只要異步任務有了運行結果,就在 "任務隊列" 之中放置一個事件。
(3)一旦 "執(zhí)行棧" 中的所有同步任務執(zhí)行完畢,系統(tǒng)就會讀取 "任務隊列",看看里面有哪些事件。那些對應的異步任務,于是結束等待狀態(tài),進入執(zhí)行棧,開始執(zhí)行。

(4)主線程不斷重復上面的第三步。

任務隊列

任務隊列分為task queue和microtask queue。執(zhí)行棧任務清空后會先從Microtasks中取任務,Microtasks中執(zhí)行完之后才會執(zhí)行task中的任務。

因此一個event loop主要流程如下:

開始一個Event loop

執(zhí)行棧從tasks queue中取任務,并執(zhí)行。

執(zhí)行完后,執(zhí)行棧清空

執(zhí)行棧從microtasks queue中取任務執(zhí)行

執(zhí)行完成,執(zhí)行棧清空

判斷microtasks queue是否還有任務,有則重復步驟3。

進入 Update the rendering(更新渲染)階段

Event loop結束

流程圖如下:

再仔細理解一下開頭列出的代碼:

for (macroTask of macroTaskQueue) {
    // 1. Handle current MACRO-TASK
    handleMacroTask();
      
    // 2. Handle all MICRO-TASK
    for (microTask of microTaskQueue) {
        handleMicroTask(microTask);
    }
}
VUE與EVENT_LOOP 為什么使用Microtask queue

對于VUE這類web2.0框架而言,最主要做的應該還是把對data的修改映射到DOM上。如果只修改一個數(shù)據(jù),就刷新一次DOM,那么在一個同步過程中,同時修改好幾個數(shù)據(jù),必然會導致多次渲染。這肯定是不可取的。
從上面的event loop我們了解到,一個event loop對應一次render。理想狀況當然就是,一次event loop產生的所有改動最好再render之前將DOM都先更新好。這樣在一個周期中就可以只render一次。

從這點需求出發(fā)很容易發(fā)現(xiàn),microtask queue很符合要求。

microtask queue肯定在render ui之前執(zhí)行完

不像task queue存在多個,microtask只存在一個queue。

最關鍵的是: microtask queue只有都清空了才能進入下一步,無論queue里是什么時候塞進來的。

實際代碼中,不管是鼠標點擊還是鍵盤輸入或是網絡時間,觸發(fā)了哪些方法,這些觸發(fā)都可以看成開啟一個event loop。這些觸發(fā)造成的任何修改都放到microtask queue中,就可以保證在這一輪的evnet loop走到render ui時可以拿到最新的DOM。

要說明的是,這里的render并不是維護虛擬DOM,也不是把虛擬DOM的變化投射到真實DOM上。而是將真實DOM更新到UI的過程。

這么說是因為:Event Loop 并不是在 ECMAScript 標準中定義的,而是在 HTML 標準中定義的:

To coordinate events, user interaction, scripts, rendering, networking, and so forth...

在 JavaScript Engine 中(以 V8 為例),只是實現(xiàn)了 ECMAScript 標準,而并不關心什么 Event Loop。也就是說 Event Loop 是屬于 JavaScript Runtime 的,是由宿主環(huán)境提供的(比如瀏覽器)。
瀏覽器可不會關心什么虛擬DOM。只負責DOM改變后渲染UI。

為什么不用task queue

同上: 在開啟一個event loop后,如果將任務放到task queue中,那么這個task任務只會在本輪Event loop結束后才會執(zhí)行,并開啟新一輪event loop。這無疑會導致兩次render UI。
實際上,尤大為了修復一些bug,曾經將VUE.nexttick用task queue實現(xiàn)。但是導致了很明顯的性能問題。
可以看看兩個列子: 例一 , 例二
兩個fiddle的實現(xiàn)一模一樣,就是讓那個絕對定位的黃色元素起到一個fixed定位的效果:綁定scroll事件,每次滾動的時候,計算當前滾動的位置并更改到那個絕對定位元素的top屬性上去。大家自己試試滾動幾下,對比下效果,你就會發(fā)現(xiàn)第一個fiddle中的黃元素是穩(wěn)定不動的,fixed很好。而后一個fiddle中就有問題了,黃色元素上下晃動,似乎跟不上我們scroll的節(jié)奏,總要慢一點,雖然最后停下滾動時位置是對的。

上述兩個例子其實是在這個issue中找到的,第一個jsfiddle使用的版本是Vue 2.0.0-rc.6,這個版本的nextTick實現(xiàn)是采用了MO,而后因為IOS9.3的WebView里的MO有bug,于是尤雨溪更改了實現(xiàn),換成了window.postMessage,也就是后一個fiddle所使用的Vue 2.0.0-rc.7。后來尤雨溪了解到window.postMessage是將回調放入的macrotask 隊列。這就是問題的根源了。

參考:

Tasks, microtasks, queues and schedules

深入理解 JavaScript Event Loop

Vue源碼詳解之nextTick:MutationObserver只是浮云,microtask才是核心!

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

轉載請注明本文地址:http://systransis.cn/yun/53049.html

相關文章

  • event loop vue

    摘要:但是導致了很明顯的性能問題。上述兩個例子其實是在這個中找到的,第一個使用的版本是,這個版本的實現(xiàn)是采用了,而后因為的里的有,于是尤雨溪更改了實現(xiàn),換成了,也就是后一個所使用的。后來尤雨溪了解到是將回調放入的隊列。 結論 對于event loop 可以抽象成一段簡單的代碼表示 for (macroTask of macroTaskQueue) { // 1. Handle cur...

    Barry_Ng 評論0 收藏0
  • JavaScript Event Loop 機制詳解 Vue.js 中實踐應用

    摘要:機制詳解與中實踐應用歸納于筆者的現(xiàn)代開發(fā)語法基礎與實踐技巧系列文章。事件循環(huán)機制詳解與實踐應用是典型的單線程單并發(fā)語言,即表示在同一時間片內其只能執(zhí)行單個任務或者部分代碼片。 JavaScript Event Loop 機制詳解與 Vue.js 中實踐應用歸納于筆者的現(xiàn)代 JavaScript 開發(fā):語法基礎與實踐技巧系列文章。本文依次介紹了函數(shù)調用棧、MacroTask 與 Micr...

    livem 評論0 收藏0
  • Vue源碼詳解之nextTick:MutationObserver只是浮云,microtask才是核

    摘要:后來尤雨溪了解到是將回調放入的隊列。而且瀏覽器內部為了更快的響應用戶,內部可能是有多個的而的的優(yōu)先級可能更高,因此對于尤雨溪采用的,甚至可能已經多次執(zhí)行了的,都沒有執(zhí)行的,也就導致了我們更新操 原發(fā)于我的博客。 前一篇文章已經詳細記述了Vue的核心執(zhí)行過程。相當于已經搞定了主線劇情。后續(xù)的文章都會對其中沒有介紹的細節(jié)進行展開。 現(xiàn)在我們就來講講其他支線任務:nextTick和micro...

    陳偉 評論0 收藏0
  • 優(yōu)秀文章收藏(慢慢消化)持續(xù)更新~

    摘要:整理收藏一些優(yōu)秀的文章及大佬博客留著慢慢學習原文協(xié)作規(guī)范中文技術文檔協(xié)作規(guī)范阮一峰編程風格凹凸實驗室前端代碼規(guī)范風格指南這一次,徹底弄懂執(zhí)行機制一次弄懂徹底解決此類面試問題瀏覽器與的事件循環(huán)有何區(qū)別筆試題事件循環(huán)機制異步編程理解的異步 better-learning 整理收藏一些優(yōu)秀的文章及大佬博客留著慢慢學習 原文:https://www.ahwgs.cn/youxiuwenzhan...

    JeOam 評論0 收藏0
  • 初探 event loop

    摘要:事件循環(huán)了解知識點線程執(zhí)行棧線程是單線程的語言可以單線程將理解為只有一條車道在車道里后面的車在等前面的車通過后才能通過即當前面的程序沒有執(zhí)行后面的程序也不能執(zhí)行執(zhí)行棧執(zhí)行棧像車道被執(zhí)行的程序會放入執(zhí)行棧里但它的執(zhí)行的順序是后面進來的程序先執(zhí) 事件循環(huán) 了解知識點 線程 執(zhí)行棧 task queue web api macro task micro task 線程 javascrip...

    hsluoyz 評論0 收藏0

發(fā)表評論

0條評論

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