欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JS的事件循環(huán)執(zhí)行機制詳解

 更新時間:2023年05月11日 10:36:44   作者:三掌柜  
JS執(zhí)行是單線程的,它是基于事件循環(huán)的,那么本篇博文就來分享一下關于JS的事件循環(huán)執(zhí)行機制,感興趣的小伙伴可以跟著小編一起來學習

前言

在前端開發(fā)中,涉及到JS原生的使用原理是非常重要的知識點,尤其是在實際工作過程中會遇到各種復雜的業(yè)務需求場景,以及具體開發(fā)中可能會遇到一些涉及基于JS原理的使用,這都要求開發(fā)者能夠很好的了解和掌握JS原生的常用原理。JS執(zhí)行是單線程的,它是基于事件循環(huán)的,那么本篇博文就來分享一下關于JS的事件循環(huán)執(zhí)行機制,該內容不僅在日常前端開發(fā)中是比較重要核心的知識點,而且在前端求職面試時候面試官必考的知識點,尤其是關于異步執(zhí)行代碼時候的事件循環(huán),總結記錄一下,方便后期查閱使用。

JS語言的特點

在分享本篇博文之前,首先再來回顧一下JS的語言特點。眾所周知,JS是單線程的,所有同步任務都在主線程上執(zhí)行,即執(zhí)行棧 execution context stack,主線程之外還存在一個任務隊列(也有人稱之為消息隊列)。也就是只能在同一個時間內做一件事情,意味著所有任務都需要排隊執(zhí)行,前面一個任務結束之后才會執(zhí)行后面一個任務,JS代碼是從上到下一行一行執(zhí)行的,如果某一行報錯,則停止執(zhí)行下面的代碼;先執(zhí)行同步代碼,再執(zhí)行異步代碼。這樣做會導致最大的問題就是如果執(zhí)行的時間比較長,就會引起頁面渲染不連貫,導致頁面渲染加載阻塞。

JS中同步和異步的使用

為了解決上面說的JS的單線程引起的頁面渲染阻塞問題,結合多核計算機的計算能力,HTML5提出了允許JS腳本創(chuàng)建多個線程的操作,至此同步和異步出現(xiàn)了。由于JS是單線程的,瀏覽器在執(zhí)行JS代碼時會先執(zhí)行同步代碼,再執(zhí)行異步代碼。

  • 同步:指的就是前一個任務結束之后再執(zhí)行后一個任務,程序執(zhí)行的順序與任務排序的順序是一樣的,保持同步的。
  • 同步任務:在主線程上排隊執(zhí)行任務,當前一個任務執(zhí)行完之后,才會執(zhí)行后一個任務。
  • 異步:首先異步與同步是相對的,也就是說異步不按照任務排序的順序執(zhí)行,程序執(zhí)行的順序與任務排序的順序是不一致的,也可以理解為異步就是從主線程中發(fā)出一個子線程來完成任務。
  • 異步任務:不用進入主線程,直接進入任務隊列的任務,只有任務隊列通知主線程某個異步任務可以執(zhí)行的時候,該任務才會進入主線程中執(zhí)行。

JS中常用的四種異步任務類型有:setTimeout、setlnterval、ES6中的Promise、Ajax異步請求、DOM事件(如:click、resize、onload)。

異步任務相關回調函數(shù)添加到任務隊列中,即消息隊列。JS中事件循環(huán)(Event Loop)的執(zhí)行機制,就是采用隊列的存取方式,在執(zhí)行和協(xié)調各種任務時,Event Loop 會維護自己的事件隊列。

事件循環(huán)是什么?

其實JS的運行機制就是事件循環(huán)。事件循環(huán)(Event Loop) 是讓JS做到既是單線程,又不會阻塞的核心機制,也是JS并發(fā)模型(Concurrency Model)的基礎,是用來協(xié)調各種事件、用戶交互、腳本執(zhí)行、UI 渲染、網絡請求等的一種機制。

下面分享一個簡單的事件循環(huán)示例代碼,具體如下所示:

//代碼語句一

console.log('a');

//代碼語句二

setTimeout(()=>{

? ? console.log('b');

},1000);

//代碼語句三

console.log('c');

//代碼執(zhí)行結果為: a,c,b

執(zhí)行過程解析:之所以出現(xiàn)上面的輸出結果,原因就是JS指向代碼是從上往下執(zhí)行,會先執(zhí)行語句一。JS會將語句一放在調用棧當中,然后執(zhí)行代碼在控制臺輸出a,當語句一執(zhí)行完畢后,便將其從調用棧中移出去;接著語句二進入調用棧,語句二會調用API, 1秒后進入回調隊列,這時候JS將語句二移出調用棧,繼續(xù)執(zhí)行后面的代碼控制臺輸出了c;這時候進入事件循環(huán),它會不斷循環(huán)的訪問回調隊列,等待1秒后API會將要執(zhí)行的語句二放入回調隊列,事件循環(huán)將回調隊列中的內容放入調用棧并執(zhí)行,然后在控制臺輸出b。

事件循環(huán)執(zhí)行過程

事件循環(huán)執(zhí)行過程:先清空調用棧里面的同步代碼,然后執(zhí)行微任務隊列中的微任務,接著DOM渲染,觸發(fā)事件循環(huán)反復輪詢回調隊列中是否有需要執(zhí)行的代碼語句,如果有就放入調用棧中繼續(xù)執(zhí)行。

  • 同步的代碼:調用棧執(zhí)行后直接出棧;
  • 異步的代碼:放到API中,等待合適的時機放入到回調隊列,等??臻e的時候事件循環(huán)開始工作,進行輪詢。

注意:微任務比宏任務執(zhí)行的時機要早,即微任務會在DOM渲染前觸發(fā),宏任務則在DOM渲染后觸發(fā)。

舉一個簡單的示例,具體代碼如下所示:

// 語句一

console.log('a');

// 語句二
setTimeout(()=>{
? ? console.log('b');
},0);

//語句三
Promise.resolve().then(()=>{
? ? console.log('c');
})

// 語句四
console.log('d');
//代碼執(zhí)行結果為:a,d,c,b

微任務和宏任務的區(qū)別

JS 中規(guī)定任務為兩類:一類是宏任務(macro task),一類是微任務(micro task),并且每個宏任務結束后,都要清空所有微任務。

  • 宏任務:當前調用棧中執(zhí)行的代碼成為宏任務,是由瀏覽器規(guī)定的,宏任務隊列由事件觸發(fā)線程維護。屬于宏任務的有:主代碼塊、定時器等。具體的宏任務如下所示:

setTimeout、setInterval、Ajax、DOM事件。

  • 微任務:當前宏任務執(zhí)行完,在下一個宏任務開始之前需要執(zhí)行的任務就叫微任務,是由ES6語法規(guī)定的,微任務隊列是由JS引擎線程維護。屬于微任務的有:promise.then,proness.nextTick 等。具體的微任務如下所示:

Promise、async、await。

JS執(zhí)行/運行機制

JS的執(zhí)行/運行機制,具體如下所示:

1、在執(zhí)行棧中執(zhí)行一個宏任務;

2、執(zhí)行過程中遇到微任務,將微任務添加到微任務隊列中;

3、當前宏任務執(zhí)行完畢,立即執(zhí)行微任務隊列中的任務;

4、當前微任務隊列中的任務執(zhí)行完畢,檢查渲染,GUI線程接管渲染;

5、渲染完畢后,js線程接管,開啟下一次事件循環(huán),執(zhí)行下一次宏任務(事件隊列中取)。

最后

通過本文關于前端開發(fā)中關于JS的事件循環(huán)執(zhí)行機制的詳細介紹,事件循環(huán)執(zhí)行機制不管是在實際的前端開發(fā)工作中還是在前端求職面試中都是非常關鍵的知識點,所以作為前端開發(fā)者來說必須要掌握它相關的內容,尤其是從事前端開發(fā)不久的開發(fā)者來說尤為重要,是一篇值得閱讀的文章,重要性就不在贅述。

以上就是JS的事件循環(huán)執(zhí)行機制詳解的詳細內容,更多關于JS事件循環(huán)執(zhí)行機制的資料請關注腳本之家其它相關文章!

相關文章

最新評論