日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

深入理解事件循环机制

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

瀏覽器常駐的線程

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

UI主線程負(fù)責(zé)協(xié)調(diào)運轉(zhuǎn)

【例】當(dāng)js引擎是單線程的,若當(dāng)前執(zhí)行的函數(shù)快沒有處理完,不會執(zhí)行下一個函數(shù)塊,此處寫一個死循環(huán)去證明該點

<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>

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

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

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

JS執(zhí)行機制

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

解釋:

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

同步任務(wù)

【例】

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

【結(jié)果】

【分析】

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

    【例】

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

    【分析】

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

    setTimeout的等待事件結(jié)束后并不是直接執(zhí)行的,而是先推入瀏覽器的一個任務(wù)隊列,在同步隊列結(jié)束后,再依次調(diào)用任務(wù)隊列中的任務(wù)

    setTimeout(function(){},0)實際上,就算JS主線程中的執(zhí)行棧為空,也達(dá)不到0毫秒,根據(jù)HTML標(biāo)準(zhǔn),最低4毫秒

    setInterval是每隔一段時間把任務(wù)放到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);

    【結(jié)果】

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

    總結(jié)

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

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。