摘要:事件循環(huán)首先來看一段代碼運行結(jié)果是先輸出,然后大概好幾秒大于一秒以后依次輸出,。原因就在以下這部分代碼中原因就是這部分循環(huán)的代碼執(zhí)行過程超過了秒。而這個循環(huán)是放在里面的。
Event-loop 事件循環(huán)
首先來看一段代碼
function fn(){ console.log("1") setTimeout(() => { console.log("2") }, 1000) var aa = 0 for (let i = 0; i < 9999999999; i++) { aa = i } if (aa = 9999999998) { console.log("3") } } fn()
運行結(jié)果是先輸出1,然后大概好幾秒(大于一秒)以后依次輸出3,2。
setTimeout(() => { console.log("2") }, 1000)
可是上邊這里明明寫了定時器一秒后輸出字符串2啊,為什么過了好久才輸出呢?這里就會引發(fā)思考,js到底是怎么執(zhí)行的
什么是JS事件循環(huán)先來一張經(jīng)典圖
我們都知道JS是單線程的,所以在它的stack(執(zhí)行棧)里面任務是排隊執(zhí)行的,這里我們在回頭看開始的代碼
function fn(){ console.log("1") setTimeout(() => { console.log("2") }, 1000) var aa = 0 for (let i = 0; i < 9999999999; i++) { aa = i } if (aa = 9999999998) { console.log("3") } } fn()
當調(diào)用fn()的時候,就會把fn這個函數(shù)放到stack中去。執(zhí)行步驟分以下幾步
第一步:執(zhí)行console.log("1")第二步:執(zhí)行到setTimeout 的時候,因為我們都知道setTimeout是異步操作,這里不可能說我js停下來等你1秒,這樣頁面就卡死在那里了。
這里在回過頭來看上面那Event-loop圖
注:js是單線程,但js是運行在瀏覽器中的,瀏覽器是多線程的,這一點要搞清楚
當我們運行到setTimeout這里時,為了不阻塞頁面,瀏覽器會在開一個線程來處理異步的操作,也就是上圖紅框框部分。然后js會略過setTimeout,繼續(xù)執(zhí)行下面for循環(huán)的代碼。
當一秒鐘之后setTimeout執(zhí)行完畢,就會將結(jié)果放如到callback queue(回調(diào)隊列中等待調(diào)用),等待stack中的任務執(zhí)行完畢后來調(diào)用它,所以一開始fn()函數(shù)的執(zhí)行結(jié)果是1,3,2,、不是1,2,3.就是因為異步的操作被放在了callback queue中,等待stack中的執(zhí)行完才會去找它。
現(xiàn)在我們搞明白了為什么結(jié)果是1,3,2 而不是1,2,3,之后還有一個問題就是為什么setTimeout明明寫的是1秒之后在控制臺打印出"2"來,為什么實際體驗中要好幾秒之后呢。原因就在以下這部分代碼中
for (let i = 0; i < 9999999999; i++) { aa = i } if (aa = 9999999998) { console.log("3") }
原因就是這部分for循環(huán)的代碼執(zhí)行過程超過了1秒。而這個for循環(huán)是放在stack里面的。它執(zhí)行不完就不會去callback queue里面找東西,所以我們看到的最終結(jié)果就是
先打印"1"出來
然后等幾秒后(這個隨電腦配置不同,時間長短不一樣),在打印出"2"
最后才會打印出"3"
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/109162.html
摘要:檢查宏任務隊列,發(fā)現(xiàn)有的回調(diào)函數(shù)立即執(zhí)行回調(diào)函數(shù)輸出。接著遇到它的作用是在后將回調(diào)函數(shù)放到宏任務隊列中這個任務在再下一次的事件循環(huán)中執(zhí)行。 為什么會寫這篇博文呢? 前段時間,和頭條的小伙伴聊天問頭條面試前端會問哪些問題,他稱如果是他面試的話,event-loop肯定是要問的。那天聊了蠻多,event-loop算是給我留下了很深的印象,原因很簡單,因為之前我從未深入了解過,如果是面試的時...
摘要:講的很清晰,看完之后更深一步的理解了事件循環(huán)機制。簡短的概述下總結(jié)是一個宏任務源,寫在里面的回調(diào)函數(shù)會加到宏任務隊列中。至此,一輪的事件循環(huán)已經(jīng)執(zhí)行完畢,開啟新的一輪事件循環(huán)。這就是整段代碼執(zhí)行情況的理解。 這篇文章真的是好文。講的很清晰,看完之后更深一步的理解了事件循環(huán)機制。 http://www.jianshu.com/p/12b9... 簡短的概述下總結(jié) setTimeout是一...
摘要:從誕生之日起就是一門單線程的非阻塞的腳本語言。這意味著這些線程實際上應屬于主線程的子線程。所以嚴格來講這些線程并沒有完整的功能,也因此這項技術(shù)并非改變了語言的單線程本質(zhì)。函數(shù)執(zhí)行棧和事件隊列 瀏覽器渲染 從耗時的角度,瀏覽器請求、加載、渲染一個頁面,時間花在下面五件事情上:1.DNS 查詢2.TCP 連接3.HTTP 請求即響應4.服務器響應5.客戶端渲染 這里重點討論第五個部分,即瀏...
摘要:所以本來快輪到你來辦理業(yè)務,會因為老大爺臨時添加的理財業(yè)務而往后推。在執(zhí)行完同步代碼與微任務以后,這時繼續(xù)向后查找有木有宏任務。所以輸出了第二次,等到這兩次都執(zhí)行完畢后才會去檢查有沒有微任務有沒有宏任務。 首先,JavaScript是一個單線程的腳本語言。 所以就是說在一行代碼執(zhí)行的過程中,必然不會存在同時執(zhí)行的另一行代碼,就像使用alert()以后進行瘋狂console.log,如...
閱讀 2812·2023-04-26 02:28
閱讀 2702·2021-09-27 13:36
閱讀 3208·2021-09-03 10:29
閱讀 2857·2021-08-26 14:14
閱讀 2179·2019-08-30 15:56
閱讀 913·2019-08-29 13:46
閱讀 2682·2019-08-29 13:15
閱讀 512·2019-08-29 11:29