JS中的進程头朱、線程、任務(wù)隊列龄减、事件循環(huán)项钮、宏任務(wù)、微任務(wù)欺殿、執(zhí)行棧等概念理解
javascript中有很多需要知道的概念寄纵,尤其是標題中列出來的這些,今天就來過一下這些概念脖苏。
一程拭、進程和線程
瀏覽器的每一個tab頁可以看做是瀏覽器內(nèi)核進程,每個進程下面會有多個線程來互相配合完成任務(wù)
比如 GUI線程棍潘、JS引擎線程恃鞋、網(wǎng)絡(luò)線程崖媚、定時器線程等
二、任務(wù)隊列
任務(wù)隊列可以當做是一個個的對調(diào)任務(wù)恤浪,當主線程的任務(wù)完成后畅哑,就開始執(zhí)行任務(wù)隊列中的任務(wù)(如果當前任務(wù)隊列中再添加了新的異步任務(wù),則其回調(diào)函數(shù)會放在之后的任務(wù)隊列中)
三水由、事件循環(huán)
異步任務(wù)執(zhí)行后荠呐,其回調(diào)會放到任務(wù)隊列中。當主線程任務(wù)執(zhí)行結(jié)束后砂客,就去任務(wù)隊列中撈接下來要做的任務(wù)泥张,放到主線程中執(zhí)行,直到任務(wù)全部結(jié)束鞠值。如果無新的任務(wù)可做媚创,瀏覽器處于等待狀態(tài),知道新的外部輸入彤恶、事件觸發(fā)钞钙,這樣一個循環(huán)過程稱為事件循環(huán)。
四声离、宏任務(wù)和微任務(wù)
任務(wù)隊列中有兩種任務(wù)芒炼,一種是宏任務(wù)一種是微任務(wù)。具體概念我也沒有查到抵恋,但是可以這樣去理解焕议,微任務(wù)就是執(zhí)行完當前主線程任務(wù)后就要馬上執(zhí)行的任務(wù),宏任務(wù)則是要放到下一次的事件循環(huán)中的主線程中的任務(wù)弧关。
一般的宏任務(wù)有setTimeout和setInterval
微任務(wù)則有promise、process.nextTick等
五唤锉、執(zhí)行棧
執(zhí)行棧是解釋器追蹤函數(shù)執(zhí)行流的一種機制世囊。當引擎第一次遇到j(luò)s代碼時,會產(chǎn)生一個全局執(zhí)行上下文壓入執(zhí)行棧窿祥,每遇到一個函數(shù)調(diào)用株憾,就往棧中壓入一個新的上下文。引擎執(zhí)行棧頂?shù)暮瘮?shù)后則彈出當前執(zhí)行上下文直至函數(shù)依次執(zhí)行完畢并回到全局的上下文晒衩。
測試
有興趣的同學(xué)可以試試下面代碼的輸出順序
setTimeout(function () {
console.log('1')
});
new Promise(function (resolve) {
console.log('2');
resolve();
}).then(function () {
console.log('3')
setTimeout(function () {
console.log('5')
});
});
console.log('4');
遇到第一個settimeout時嗤瞎,先把整體代碼塊放到第一個宏任務(wù)中,遇到promise听系,先執(zhí)行內(nèi)部的代碼贝奇,把then中的代碼放到為任務(wù)中。遇到console.log(4)在主線程中直接執(zhí)行靠胜。之后先從微任務(wù)中撈取任務(wù)執(zhí)行 console.log(3)并把后面的setTimeout放到下一個宏任務(wù)隊列(第二個)中掉瞳。然后從當前宏任務(wù)隊列中撈取要執(zhí)行的代碼毕源,打印1。然后開始到下一個事件循環(huán)陕习,把宏任務(wù)的代碼撈出來執(zhí)行霎褐。
所以順序是24315