2020国产成人精品视频,性做久久久久久久久,亚洲国产成人久久综合一区,亚洲影院天堂中文av色

分享

事件循環(huán) EventLoop(Promise,setTimeOut,async/await執(zhí)行順序)

 Coder編程 2021-08-23

什么是事件循環(huán)?想要了解什么是事件循環(huán)就要從js的工作原理開始說起:

JS主要的特點(diǎn)就是單線程,所謂單線程就是進(jìn)程中只有一個(gè)線程在運(yùn)行。

為什么JS是單線程的而不是多線程的呢?

JS的主要用途就是與用戶交互,操作DOM,假設(shè)JS同時(shí)有兩個(gè)線程,一個(gè)線程中在某個(gè)DOM節(jié)點(diǎn)上添加或者修改內(nèi)容,而另一個(gè)線程在這個(gè)DOM節(jié)點(diǎn)上執(zhí)行刪除該節(jié)點(diǎn)操作,這樣就會(huì)產(chǎn)生沖突。

單線程就意味著所有任務(wù)都需要排隊(duì),前一任務(wù)結(jié)束,才會(huì)執(zhí)行后一個(gè)任務(wù),當(dāng)是如果當(dāng)遇到前一個(gè)任務(wù)耗時(shí)很長的情況,后一個(gè)任務(wù)就不得不一直等著。因此,就有了同步任務(wù)、異步任務(wù)。

同步任務(wù)和異步任務(wù)在js中是如何執(zhí)行的呢?

js的代碼運(yùn)行會(huì)形成一個(gè)主線程和一個(gè)任務(wù)隊(duì)列。主線程會(huì)自上而下依次執(zhí)行我們的js代碼,形成一個(gè)執(zhí)行棧。

同步任務(wù)就會(huì)被放到這個(gè)主線程中依次執(zhí)行。而異步任務(wù)被放入到任務(wù)隊(duì)列中執(zhí)行,執(zhí)行完就會(huì)在任務(wù)隊(duì)列中打一個(gè)標(biāo)記,形成一個(gè)對(duì)應(yīng)的事件。當(dāng)主線程中的任務(wù)全部運(yùn)行完畢,js會(huì)去提取并執(zhí)行任務(wù)隊(duì)列中的事件。這個(gè)過程是循環(huán)進(jìn)行的,這就是EventLoop。

JS引擎執(zhí)行異步代碼不用等待,是因?yàn)橛惺录?duì)列和事件循環(huán)。

事件循環(huán)是指主線程重復(fù)從事件隊(duì)列中取消息、執(zhí)行的過程。指整個(gè)執(zhí)行流程。

事件隊(duì)列是一個(gè)存儲(chǔ)著待執(zhí)行任務(wù)的序列,其中的任務(wù)嚴(yán)格按照時(shí)間先后順序執(zhí)行,排在隊(duì)頭的任務(wù)會(huì)率先執(zhí)行,而排在隊(duì)尾的任務(wù)會(huì)最后執(zhí)行。(即先進(jìn)先出)

事件隊(duì)列:

  • 一個(gè)線程中,事件循環(huán)是唯一的,但是任務(wù)隊(duì)列可以有多個(gè);
  • 任務(wù)隊(duì)列又分macro-task(宏任務(wù))和micro-task(微任務(wù));
  • macro-task包括:script(整體代碼)、setTimeout、setInterval、setImmediate、I/O、UI rendering;
  • micro-task包括:process.nextTick, Promise, Object.observe(已廢棄), MutationObserver(html5新特性)
  • setTimeout/Promise等稱為任務(wù)源,而進(jìn)入任務(wù)隊(duì)列的是他們制定的具體執(zhí)行任務(wù);來自不同任務(wù)源的任務(wù)會(huì)進(jìn)入到不同的任務(wù)隊(duì)列,其中setTimeout與setInterval是同源的。
 

事件循環(huán)運(yùn)行機(jī)制

(1)執(zhí)行一個(gè)宏任務(wù)(棧中沒有就從事件隊(duì)列中獲?。?/p>

(2)執(zhí)行過程中如果遇到微任務(wù),就將它添加到微任務(wù)的任務(wù)隊(duì)列中;

(3)宏任務(wù)執(zhí)行完畢后,立即執(zhí)行當(dāng)前微任務(wù)隊(duì)列的所有微任務(wù);

(4)當(dāng)前微任務(wù)執(zhí)行完畢,開始檢查渲染,然后GUI線程接管渲染;

(5)渲染完畢后,JS線程繼續(xù)接管,開始下一個(gè)宏任務(wù)。

 

 

事例:

                 async function async1() {           
                     console.log("async1 start");  //(2)        
                     await  async2();            
                     console.log("async1 end");   //(6)    
                 }        
                 async  function async2() {          
                     console.log( 'async2');   //(3)     
                 }       
                 console.log("script start");  //(1)      
                 setTimeout(function () {            
                     console.log("settimeout");  //(8)      
                 },0);        
                 async1();        
                 new Promise(function (resolve) {           
                     console.log("promise1");   //(4)         
                     resolve();        
                 }).then(function () {            
                     console.log("promise2");    //(7)    
                 });        
                 console.log('script end');//(5)

 

按照事件循環(huán)機(jī)制分析以上代碼運(yùn)行流程:

  1. 首先,事件循環(huán)從宏任務(wù)(macrotask)隊(duì)列開始,首先讀取script(整體代碼)任務(wù);當(dāng)遇到任務(wù)源(task source)時(shí),則會(huì)先分發(fā)任務(wù)到對(duì)應(yīng)的任務(wù)隊(duì)列中去。

  2. 然后我們看到首先定義了兩個(gè)async函數(shù),此時(shí)沒有調(diào)用,接著往下看,然后遇到了 `console` 語句,直接輸出 `script start`。輸出之后,script 任務(wù)繼續(xù)往下執(zhí)行,遇到 `setTimeout`,其作為一個(gè)宏任務(wù)源,則會(huì)先將其任務(wù)分發(fā)到對(duì)應(yīng)的任務(wù)隊(duì)列中。

  3. script 任務(wù)繼續(xù)往下執(zhí)行,執(zhí)行了async1()函數(shù),async函數(shù)中在await之前的代碼是立即執(zhí)行的,所以會(huì)立即輸出`async1 start`。
遇到了await時(shí),會(huì)將await后面的表達(dá)式執(zhí)行一遍,所以就緊接著輸出`async2`,然后將await后面的代碼也就是`console.log('async1 end')`加入到microtask中的Promise隊(duì)列中,接著跳出async1函數(shù)來執(zhí)行后面的代碼。

  4. script任務(wù)繼續(xù)往下執(zhí)行,遇到Promise實(shí)例。由于Promise中的函數(shù)是立即執(zhí)行的,而后續(xù)的 `.then` 則會(huì)被分發(fā)到 microtask 的 `Promise` 隊(duì)列中去。所以會(huì)先輸出 `promise1`,然后執(zhí)行 `resolve`,將 `promise2` 分配到對(duì)應(yīng)隊(duì)列。

  5. script任務(wù)繼續(xù)往下執(zhí)行,輸出了 `script end`,至此,全局任務(wù)就執(zhí)行完畢了。
根據(jù)上述,每次執(zhí)行完一個(gè)宏任務(wù)之后,會(huì)去檢查是否存在 Microtasks;如果有,則執(zhí)行 Microtasks 直至清空 Microtask Queue。
因而在script任務(wù)執(zhí)行完畢之后,開始查找清空微任務(wù)隊(duì)列。此時(shí),微任務(wù)中, `Promise` 隊(duì)列有的兩個(gè)任務(wù)`async1 end`和`promise2`,因此按事件隊(duì)列先進(jìn)先出的原則,先后順序輸出 `async1 end,promise2`。當(dāng)所有的 Microtasks 執(zhí)行完畢之后,表示第一輪的循環(huán)就結(jié)束了。

  6. 第二輪循環(huán)依舊從宏任務(wù)隊(duì)列開始。此時(shí)宏任務(wù)中只有一個(gè) `setTimeout`,取出直接輸出即可,至此整個(gè)流程結(jié)束。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多