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

詳解JavaScript事件循環(huán)

 更新時間:2023年04月19日 11:27:02   作者:Nooo_47  
JavaScript事件循環(huán)是一種機(jī)制,用于處理異步事件和回調(diào)函數(shù)。它是JavaScript運(yùn)行時環(huán)境的一部分,負(fù)責(zé)管理事件隊(duì)列和調(diào)用棧。文章中有詳細(xì)的代碼示例,需要的朋友可以參考一下

JavaScript事件循環(huán)是一種機(jī)制,用于處理異步事件和回調(diào)函數(shù)。它是JavaScript運(yùn)行時環(huán)境的一部分,負(fù)責(zé)管理事件隊(duì)列和調(diào)用棧。

事件循環(huán)的基本原理是事件循環(huán)的核心是一個事件隊(duì)列,所有的事件都被放入這個隊(duì)列中,然后按照順序依次執(zhí)行。如果隊(duì)列為空,JavaScript會等待新的任務(wù)加入隊(duì)列。當(dāng)JavaScript代碼執(zhí)行時,所有同步任務(wù)都會被立即執(zhí)行,而異步任務(wù)則會被放入事件隊(duì)列中。

當(dāng)所有同步任務(wù)執(zhí)行完畢后,事件循環(huán)會從事件隊(duì)列中取出一個任務(wù),并將其放入調(diào)用棧中執(zhí)行。當(dāng)該任務(wù)執(zhí)行完畢后,事件循環(huán)會再次從事件隊(duì)列中取出下一個任務(wù),并重復(fù)這個過程。

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

1、執(zhí)行同步代碼,直到遇到第一個異步事件(如setTimeout、setInterval、Promise等)。

2、將異步事件放入事件隊(duì)列中,并繼續(xù)執(zhí)行同步代碼。

3、當(dāng)所有同步代碼執(zhí)行完畢后,JavaScript引擎會檢查事件隊(duì)列中是否有事件需要執(zhí)行。

4、如果事件隊(duì)列中有事件需要執(zhí)行,JavaScript引擎會將第一個事件取出來,并執(zhí)行對應(yīng)的回調(diào)函數(shù)。

5、執(zhí)行完回調(diào)函數(shù)后,JavaScript引擎會再次檢查事件隊(duì)列中是否有事件需要執(zhí)行,如果有則重復(fù)步驟4,否則繼續(xù)等待新的事件加入事件隊(duì)列。

需要注意的是,事件循環(huán)是單線程的,也就是說JavaScript引擎在同一時間只能執(zhí)行一個任務(wù)。

因此,如果一個任務(wù)執(zhí)行時間過長,會阻塞事件循環(huán),導(dǎo)致其他任務(wù)無法執(zhí)行。為了避免這種情況,可以將長時間的任務(wù)拆分成多個小任務(wù),使用setTimeout或setInterval分批執(zhí)行。

另外,Promise也是基于事件循環(huán)的機(jī)制實(shí)現(xiàn)的。當(dāng)Promise狀態(tài)發(fā)生改變時,會將對應(yīng)的回調(diào)函數(shù)放入微任務(wù)隊(duì)列中,等待當(dāng)前任務(wù)執(zhí)行完畢后立即執(zhí)行。因此,Promise的回調(diào)函數(shù)總是在當(dāng)前任務(wù)執(zhí)行完畢后立即執(zhí)行,而不會被放入事件隊(duì)列中等待執(zhí)行。

二、事件循環(huán)進(jìn)階用法

1、Promise:Promise是一種異步編程的解決方案,它可以將異步操作轉(zhuǎn)化為同步操作的形式,使得代碼更加簡潔易懂。Promise的基本原理是將異步操作封裝成一個Promise對象,通過then方法來處理異步操作的結(jié)果。

2、async/await:async/await是ES2017引入的一種異步編程的解決方案,它可以讓異步代碼看起來像同步代碼,使得代碼更加易讀易懂。async/await的基本原理是使用async關(guān)鍵字定義一個異步函數(shù),然后在函數(shù)內(nèi)部使用await關(guān)鍵字來等待異步操作的結(jié)果。

3、定時器:JavaScript中有兩種定時器,分別是setTimeout和setInterval。setTimeout用于在指定的時間后執(zhí)行一次任務(wù),而setInterval則用于每隔一段時間執(zhí)行一次任務(wù)。這兩種定時器都是異步任務(wù),會被放入任務(wù)隊(duì)列中等待執(zhí)行。

三、JavaScript任務(wù)類型

JavaScript中的任務(wù)按照不同緯度進(jìn)行區(qū)分主要分為同步任務(wù)和異步任務(wù)、宏任務(wù)和微任務(wù)。

3.1 同步任務(wù)&異步任務(wù)

1、 同步任務(wù)按照代碼順序執(zhí)行的任務(wù)。

2、 異步任務(wù)是在將來某個時間點(diǎn)執(zhí)行的任務(wù)。異步任務(wù)通常是由事件觸發(fā)器(如鼠標(biāo)點(diǎn)擊、網(wǎng)絡(luò)請求等)生成的。 當(dāng)一個異步任務(wù)被觸發(fā)時,它會被放入任務(wù)隊(duì)列中等待執(zhí)行。

JavaScript事件循環(huán)的執(zhí)行順序可以用以下偽代碼表示:

while (queue.waitForMessage()) { 
    queue.processNextMessage(); 
} 

在這個偽代碼中,queue.waitForMessage()表示等待隊(duì)列中有待執(zhí)行的任務(wù),queue.processNextMessage()表示取出隊(duì)列中的下一個任務(wù)并執(zhí)行。

需要注意的是,JavaScript事件循環(huán)的執(zhí)行順序是不可中斷的。這意味著當(dāng)一個任務(wù)正在執(zhí)行時,其他任務(wù)必須等待,直到當(dāng)前任務(wù)完成。因此,如果一個任務(wù)執(zhí)行時間過長,會導(dǎo)致其他任務(wù)無法及時執(zhí)行,從而影響應(yīng)用程序的性能和響應(yīng)速度。

3.2 宏任務(wù)&微任務(wù)

1、宏任務(wù)包括setTimeout、setInterval、I/O操作等。

2、微任務(wù)包括Promise、MutationObserver等。

當(dāng)事件循環(huán)從事件隊(duì)列中取出一個任務(wù)時,它會先執(zhí)行所有微任務(wù),然后再執(zhí)行一個宏任務(wù)。這個過程會一直重復(fù),直到事件隊(duì)列中的所有任務(wù)都被執(zhí)行完畢。

下面是一個例子:

console.log('1'); 

setTimeout(function() { 
    console.log('2'); 
    Promise.resolve().then(function() { 
        console.log('3'); 
    }); 
}, 0); 

Promise.resolve().then(function() { 
    console.log('4'); 
}); 
console.log('5'); 

// 輸出結(jié)果為: 1 5 4 2 3 

執(zhí)行順序:

  • 執(zhí)行第一個console.log,輸出1。
  • 執(zhí)行setTimeout,將其回調(diào)函數(shù)放入宏任務(wù)隊(duì)列中。
  • 執(zhí)行Promise.resolve().then,將其回調(diào)函數(shù)放入微任務(wù)隊(duì)列中。
  • 執(zhí)行第二個console.log,輸出5。
  • 當(dāng)前任務(wù)執(zhí)行結(jié)束,執(zhí)行微任務(wù)隊(duì)列中的所有任務(wù),輸出4。
  • 執(zhí)行宏任務(wù)隊(duì)列中的第一個任務(wù),即setTimeout的回調(diào)函數(shù),輸出2。
  • 執(zhí)行Promise.resolve().then的回調(diào)函數(shù),輸出3。

需要注意的是,微任務(wù)和宏任務(wù)的執(zhí)行順序是固定的,即先執(zhí)行所有微任務(wù),再執(zhí)行宏任務(wù)。因此,如果在一個宏任務(wù)中產(chǎn)生了新的微任務(wù),那么這些微任務(wù)會在下一個宏任務(wù)執(zhí)行之前執(zhí)行。

下面是一個例子:

console.log('1'); 

setTimeout(function() { 
    console.log('2'); 
    Promise.resolve().then(function() { 
        console.log('3'); 
    }); 
}, 0); 

Promise.resolve().then(function() { 
    console.log('4'); 
    setTimeout(function() { 
        console.log('5'); 
    }, 0); 
}); 

console.log('6'); 

// 輸出結(jié)果為:1 6 4 2 3 5

執(zhí)行順序:

  • 執(zhí)行第一個console.log,輸出1。
  • 執(zhí)行setTimeout,將其回調(diào)函數(shù)放入宏任務(wù)隊(duì)列中。
  • 執(zhí)行Promise.resolve().then,將其回調(diào)函數(shù)放入微任務(wù)隊(duì)列中。
  • 執(zhí)行第三個console.log,輸出6。
  • 當(dāng)前任務(wù)執(zhí)行結(jié)束,執(zhí)行微任務(wù)隊(duì)列中的所有任務(wù),輸出4。
  • 執(zhí)行宏任務(wù)隊(duì)列中的第一個任務(wù),即setTimeout的回調(diào)函數(shù),輸出2。
  • 執(zhí)行Promise.resolve().then的回調(diào)函數(shù),將setTimeout的回調(diào)函數(shù)放入宏任務(wù)隊(duì)列中。
  • 當(dāng)前任務(wù)執(zhí)行結(jié)束,執(zhí)行微任務(wù)隊(duì)列中的所有任務(wù),輸出3。
  • 執(zhí)行宏任務(wù)隊(duì)列中的第一個任務(wù),即setTimeout的回調(diào)函數(shù),輸出5。

到此這篇關(guān)于詳解JavaScript事件循環(huán)的文章就介紹到這了,更多相關(guān)JavaScript事件循環(huán)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論