前言
javascript是單線程的語言,也就是說,同一個時間只能做一件事。而這個單線程的特性,與它的用途有關,作為瀏覽器腳本語言,JavaScript的主要用途是與用戶互動,以及操作DOM。這決定了它只能是單線程,否則會帶來很復雜的同步問題。比如,假定JavaScript同時有兩個線程,一個線程在某個DOM節點上添加內容,另一個線程刪除了這個節點,這時瀏覽器應該以哪個線程為準?
為了利用多核CPU的計算能力,HTML5提出Web Worker標準,允許JavaScript腳本創建多個線程,但是子線程完全受主線程控制,且不得操作DOM。所以,這個新標準并沒有改變JavaScript單線程的本質
這是今天一個朋友發給我的一個面試題,
感覺還挺有意思的,
寫個博客以供分享
先看看這個面試題目:
觀察下面的代碼,寫出輸出結果
console.log('0')setTimeout(function () { console.log('1');});new Promise(function(resolve,reject){ console.log('2') resolve(3)}).then(function(val){ console.log(val)})console.log(4)
輸出結果: “0” “2” 4 3 “1”
今天主要是分析為什么輸出結果是這樣的?這就和 javascript 的執行機制密切相關了.
Event Queue 和 Event Loop
javascript 是一門單線程的語言, 這就意味著在執行代碼的時候, 都只有一個主線程來處理所有的任務.
我們都知道 javascript 包括同步代碼和異步代碼, 那么 javascript 是怎么處理這兩種情況的呢?
這里我們引進了 Event Queue 事件隊列這一概念. 所有異步操作的回調都會進入到這里. 然后等到主線程空閑, 就會從這里調取回調執行.
setTimeout
setTimeout 相信大家都有使用過, 可以延時執行并且是異步執行的.
但是有時候我們得到的結果往往是代碼實際執行的時間比我們想要延時執行的時間要久。這又是為什么呢?
這就和我們之前所說的 Event Loop 有關了, 我們可以來具體看下 setTimeout 的執行步驟:
setTimeout(function () {asyncFn()}, 1000);syncFn()
所以有時候會出現代碼實際執行時間比延時時間長的情況。
宏任務和微任務
之前我們說過異步任務會進入到事件隊列中, 不同類型的任務會進入到不同的隊列中, 比如宏任務會進入到宏任務隊列中, 微任務會進入到微任務隊列中.
我們只要記住 當當前執行棧執行完畢時會立刻先處理所有微任務隊列中的事件,然后再去宏任務隊列中取出一個事件。同一次事件循環中,微任務永遠在宏任務之前執行
這時候我們就可以解釋一開始的代碼執行結果了:
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對VeVb武林網的支持。
新聞熱點
疑難解答