日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

深入理解事件循环机制

發布時間:2024/2/28 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 深入理解事件循环机制 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

瀏覽器常駐的線程

  • js引擎線程(解釋執行js代碼、用戶輸入、網絡請求)
  • GUI線程(繪制用戶界面、與js主線程是互斥的)
  • http網絡請求線程(處理用戶的get,post等請求,等返回結果后將回調函數推入任務隊列)
  • 定時器觸發線程(setTimeout,setIntervat等待事件結束后把執行函數推入任務隊列中)
  • 瀏覽器事件處理線程(將click,mouse等交互事件發生后將這些事件放入事件隊列中)

UI主線程負責協調運轉

【例】當js引擎是單線程的,若當前執行的函數快沒有處理完,不會執行下一個函數塊,此處寫一個死循環去證明該點

<body><button id="btn">run</button> </body> <script type="text/javascript"> var oBtn = document.getElementById('btn'); function dieLoop() {while (true) {} } oBtn.onclick = function () {console.log("a"); } </script>

【結果】點擊按鈕打印"a",執行函數dieLoop(作死的人才去執行這個函數,反正我卡死了),再點擊按鈕,不執行該點擊事件

JS引擎線程和GUI線程—互斥

JS可以操作DOM元素,進而會影響到GUI的渲染結果因此JS引擎線程與GU渲染線程是互斥的。也就是說當JS引擎線程處于運行狀態時,GUI渲染線程將處于凍結狀態。

JS執行機制

  • 單線程—同一時間只能做一件事
  • 使用單線程的原因:js設計出來就是為了與用戶交互,處理DOM,假如js是多線程,同一時間一個線程想要修改DOM,另一個線程想要刪除DOM,問題就變得復雜許多,問題就變得復雜,如果引入“鎖”的機制,就回到了被其他語言尷尬的困境(什么被其他語言尷尬的困境?)
  • 操作大量數據的解決辦法:單線程計算能力有限,大量數據需要計算渲染的話,需要配合后端進行操作(VUE和node.js配合,即SSR技術)
  • 異步執行:JAvaScript是基于單線程運行的,同時又可以異步執行,一般來說這種既是單線程又是異步的語言都是基于事件來驅動的,恰好瀏覽器給JavaScript提供了這樣的環境
  • 流程圖如下

解釋:

  • 同步和異步任務分別進入不同的執行“場所”,同步的進入主線程,異步的進入Event Table并注冊函數
  • 當指定的事情完成時,Event Table會將這個函數移入Event Queue
  • 主線程內的任務執行完畢為空,會去Event Queue讀取對應的函數,進入主線程執行,
  • 上述過程不斷重復,即Event Loop(事件循環)

同步任務

【例】

function foo(ot) {function bar(it) {debugger;console.log(it);}bar(10);console.log(ot); } foo(20);

【結果】

【分析】

  • 代碼沒有執行的時候,執行棧為空;
  • foo函數執行時,創建一幀,其中包含形參、局部變量(預編譯過程),然后把這一幀壓入棧中;
  • 執行foo函數中的bar函數;
  • 創建一幀,壓入棧中;
  • bar函數執行完畢,彈出棧;
  • foo函數執行完畢,彈出棧;
  • 執行棧為空。
  • 異步任務

    【例】

    $.ajax({url : '',data : {},success : function (data) {console.log(data);} }); console.log('run');

    【分析】

  • Aja進入Event Table,注冊回調函數success;
  • 執行 console.log('run');
  • Ajax事件完成http網絡請求線程,把任務放入任務隊列Event Queue中
  • 主線程讀取任務執行success函數
  • 深入理解定時器

    setTimeout的等待事件結束后并不是直接執行的,而是先推入瀏覽器的一個任務隊列,在同步隊列結束后,再依次調用任務隊列中的任務

    setTimeout(function(){},0)實際上,就算JS主線程中的執行棧為空,也達不到0毫秒,根據HTML標準,最低4毫秒

    setInterval是每隔一段時間把任務放到Event Queue之中

    【例】

    var firstTime = + new Date(); function loop(d) {for (var i = 0; i < d; i++) {console.log(i);} } loop(10000); setTimeout(function () {var time = + new Date() - firstTime;console.log(time); },100);

    【結果】

    【分析】setTimeout并不是100毫秒之后執行的,而是100毫秒后放入任務隊列,在同步隊列的任務執行完畢后,執行任務隊列的setTimeout。

    總結

    以上是生活随笔為你收集整理的深入理解事件循环机制的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。