亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

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

前言

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

JS語言的特點(diǎn)

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

JS中同步和異步的使用

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

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

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

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

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

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

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

//代碼語句一

console.log('a');

//代碼語句二

setTimeout(()=>{

? ? console.log('b');

},1000);

//代碼語句三

console.log('c');

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

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

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

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

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

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

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

// 語句一

console.log('a');

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

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

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

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

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

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

setTimeout、setInterval、Ajax、DOM事件。

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

Promise、async、await。

JS執(zhí)行/運(yùn)行機(jī)制

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

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

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

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

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

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

最后

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

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

相關(guān)文章

最新評論