摘要:換個(gè)說(shuō)法微任務(wù)優(yōu)先于當(dāng)前調(diào)用棧產(chǎn)生的宏任務(wù)被執(zhí)行如果能理解下面這段代碼的執(zhí)行過(guò)程應(yīng)該就基本理解任務(wù)隊(duì)列的執(zhí)行過(guò)程了輸出順序?yàn)?,,,,,?/p>
這篇文章是我自己的一個(gè)學(xué)習(xí)總結(jié),并不是非常詳細(xì),結(jié)合給出的鏈接可以有更細(xì)致的認(rèn)識(shí)
先介紹幾個(gè)概念,便于理解
關(guān)于堆和棧(作為內(nèi)存區(qū)域來(lái)說(shuō))堆(heap):存放object、array、function等不確定內(nèi)存大小的數(shù)據(jù)存儲(chǔ);
棧(stack):存放基本數(shù)據(jù)類(lèi)型以及引用數(shù)據(jù)類(lèi)型指向堆中的數(shù)據(jù)的指針,具有具體大小的數(shù)據(jù)結(jié)構(gòu),存取速度快;
調(diào)用棧(作為一種代碼運(yùn)行機(jī)制)call stack(調(diào)用棧)指的是函數(shù)調(diào)用運(yùn)行的機(jī)制,具體參考該鏈接:javascrip調(diào)用棧
事件循環(huán)機(jī)制(event loop)參考:js事件循環(huán)機(jī)制
存在整個(gè)javascript腳本執(zhí)行期間
作用:將任務(wù)隊(duì)列的中可以執(zhí)行的函數(shù)壓入調(diào)用棧中
任務(wù)隊(duì)列(task queue)任務(wù)隊(duì)列主要分為兩種:
宏任務(wù)(macro task):在新標(biāo)準(zhǔn)中叫task
宏任務(wù)主要包括:script(整體代碼), setTimeout, setInterval, setImmediate, I/O, UI rendering
微任務(wù)(micro task):在新標(biāo)準(zhǔn)中叫jobs
微任務(wù)主要包括:process.nextTick, Promise, Object.observe(已廢棄), MutationObserver(html5新特性)
以上提到的不只有瀏覽器方法,還有nodejs的方法,這里不具體說(shuō)明了
執(zhí)行特點(diǎn):每當(dāng)調(diào)用棧為空時(shí),事件循環(huán)機(jī)制會(huì)將一個(gè)宏任務(wù)隊(duì)列中任務(wù)壓入調(diào)用棧中
以空的調(diào)用棧為起點(diǎn)的話(huà),先執(zhí)行所有宏任務(wù),再執(zhí)行所有微任務(wù),然后調(diào)用棧又為空,這樣一次可以看作一個(gè)單元,之后就是一直在循環(huán)執(zhí)行這樣單元
分解執(zhí)行過(guò)程:
執(zhí)行所有調(diào)用棧中的宏任務(wù)
宏任務(wù)執(zhí)行過(guò)程中產(chǎn)生的微任務(wù)加入到微任務(wù)隊(duì)列
宏任務(wù)執(zhí)行完立刻執(zhí)行所有微任務(wù)隊(duì)列中的任務(wù)
以上執(zhí)行完畢,檢查渲染,GUI線程接管渲染
渲染完畢后,js線程接管,開(kāi)啟下一次事件循環(huán)(每一次事件循環(huán)(script不包括),只處理一個(gè)宏任務(wù)),執(zhí)行下一次宏任務(wù)(任務(wù)隊(duì)列中取)
不好理解的地方:
以上過(guò)程(無(wú)論宏任務(wù)還是微任務(wù)執(zhí)行)中產(chǎn)生的宏任務(wù)進(jìn)入宏任務(wù)隊(duì)列等待,進(jìn)入后面的循環(huán)執(zhí)行,不在當(dāng)次循環(huán)中被執(zhí)行
但是以上過(guò)程中(包括微任務(wù))產(chǎn)生的微任務(wù)又會(huì)被立刻放到當(dāng)次循環(huán)的微任務(wù)隊(duì)列后面按順序執(zhí)行
以上兩句可能有點(diǎn)繞,可以參考上面循環(huán)機(jī)制的鏈接,有相關(guān)圖解。
換個(gè)說(shuō)法:微任務(wù)優(yōu)先于當(dāng)前調(diào)用棧產(chǎn)生的宏任務(wù)被執(zhí)行
如果能理解下面這段代碼的執(zhí)行過(guò)程應(yīng)該就基本理解任務(wù)隊(duì)列的執(zhí)行過(guò)程了:
setTimeout(() => { console.log("1") new Promise((resolve) => { resolve() }).then(() => { console.log("2") }) }, 0); setTimeout(() => { console.log("3") }, 0); new Promise((resolve) => { resolve() }).then(() => { console.log("4") new Promise((resolve) => { resolve() }).then(() => { console.log("5") }) setTimeout(() => { console.log("6") }, 0); }) new Promise((resolve) => { resolve() }).then(() => { console.log("7") }) // 輸出順序?yàn)椋?4,7,5,1,2,3,6
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/97486.html
摘要:從異步過(guò)程的角度看,函數(shù)就是異步過(guò)程的發(fā)起函數(shù),事件監(jiān)聽(tīng)函數(shù)就是異步過(guò)程的回調(diào)函數(shù)。事件觸發(fā)時(shí),表示異步任務(wù)完成,會(huì)將事件監(jiān)聽(tīng)器函數(shù)封裝成一條消息放到消息隊(duì)列中,等待主線程執(zhí)行。 1.為什么JavaScript是單線程? JavaScript語(yǔ)言的一大特點(diǎn)就是單線程,也就是說(shuō),同一個(gè)時(shí)間只能做一件事。那么,為什么JavaScript不能有多個(gè)線程呢?這樣能提高效率啊。JavaScrip...
摘要:接下來(lái)處理微任務(wù)隊(duì)列,打印,后面一個(gè)不會(huì)有任何打印,但是會(huì)執(zhí)行執(zhí)行后面的代碼打印進(jìn)入第二次事件循環(huán),執(zhí)行宏任務(wù)隊(duì)列打印 事件循環(huán)機(jī)制 理解js的事件循環(huán)機(jī)制,能夠很大程度的幫我們更深層次的理解平時(shí)遇到的一些很疑惑的問(wèn)題 簡(jiǎn)單版本 下面來(lái)看一段代碼,想想它的結(jié)果和你的結(jié)果是否一樣 setTimeout(function() { console.log(1) ...
摘要:異步請(qǐng)求線程在在連接后是通過(guò)瀏覽器新開(kāi)一個(gè)線程請(qǐng)求將檢測(cè)到狀態(tài)變更時(shí),如果設(shè)置有回調(diào)函數(shù),異步線程就產(chǎn)生狀態(tài)變更事件,將這個(gè)回調(diào)再放入事件循環(huán)隊(duì)列中。 基礎(chǔ):瀏覽器 -- 多進(jìn)程,每個(gè)tab頁(yè)獨(dú)立一個(gè)瀏覽器渲染進(jìn)程(瀏覽器內(nèi)核) 每個(gè)瀏覽器渲染進(jìn)程是多線程的,主要包括:GUI渲染線程 JS引擎線程 也稱(chēng)為JS內(nèi)核,負(fù)責(zé)處理Javascript腳本程序。(例如V8引擎) JS引擎線程負(fù)...
摘要:的單線程,與它的用途有關(guān)。只要指定過(guò)回調(diào)函數(shù),這些事件發(fā)生時(shí)就會(huì)進(jìn)入任務(wù)隊(duì)列,等待主線程讀取。四主線程從任務(wù)隊(duì)列中讀取事件,這個(gè)過(guò)程是循環(huán)不斷的,所以整個(gè)的這種運(yùn)行機(jī)制又稱(chēng)為事件循環(huán)。令人困惑的是,文檔中稱(chēng),指定的回調(diào)函數(shù),總是排在前面。 原文:http://www.cnblogs.com/Master... 一、為什么JavaScript是單線程? JavaScript語(yǔ)言的一大特點(diǎn)...
摘要:而這些隊(duì)列由的事件循環(huán)來(lái)搞定宏任務(wù)與微任務(wù),在最新標(biāo)準(zhǔn)中,它們被分別稱(chēng)為與。我們梳理一下事件循環(huán)的執(zhí)行機(jī)制循環(huán)首先從宏任務(wù)開(kāi)始,遇到,生成執(zhí)行上下文,開(kāi)始進(jìn)入執(zhí)行棧,可執(zhí)行代碼入棧,依次執(zhí)行代碼,調(diào)用完成出棧。 寫(xiě)在前面 js是一門(mén)單線程的編程語(yǔ)言,也就是說(shuō)js在處理任務(wù)的時(shí)候,所有任務(wù)只能在一個(gè)線程上排隊(duì)被執(zhí)行,那如果某一個(gè)任務(wù)耗時(shí)比較長(zhǎng)呢?總不能等到它執(zhí)行結(jié)束再去執(zhí)行下一個(gè)。所以在...
閱讀 3087·2023-04-26 02:04
閱讀 1342·2021-11-04 16:07
閱讀 3814·2021-09-22 15:09
閱讀 739·2019-08-30 15:54
閱讀 1964·2019-08-29 14:11
閱讀 2599·2019-08-26 12:19
閱讀 2332·2019-08-26 12:00
閱讀 837·2019-08-26 10:27