JavaScript 事件循環

js是一門單線程的語言,不可能進行多線程編程,異步編程就是多線程編程一種模式,可是咱們常常講到js的異步編程,實際上是僞異步,由於它是單線程的,也就是同步,只有前面的代碼執行完才能執行下面的代碼。因此要理解js中的異步理念,就須要瞭解js的運行核心--事件循環(Event loop)html

爲何js會有異步呢

setTimeout(function(){
    //5秒以後執行程序
    
},5000)

咱們想象一下,在同步的執行上面的代碼,須要等待5秒才能執行定時器中的程序,而後在往下執行,在這5秒的過程當中,瀏覽器沒有任何反應,出現了阻塞,在用戶體驗上很很差。因此異步的模式就出現,爲了解決瀏覽器非阻塞的運行。html5

單線程如何作到異步

js的任務分爲同步異步兩種,它們的處理方式也不一樣,同步任務是直接在主線程上排隊執行,異步任務則會被放到事件隊列中,如有多個異步任務則要在事件隊列中排隊等待,事件隊列相似一個緩衝區,任務下一步會被移到調用棧,而後主線程執行調用棧的任務。web

單線程是指js引擎中負責解析執行js代碼的線程只有一個主線程,即每次只能作一件事,而咱們知道一個ajax請求,主線程在等待它響應的同時是會去作其它事的,瀏覽器先在事件表註冊ajax的回調函數,響應回來後回調函數被添加到任務隊列中等待執行,不會形成線程阻塞,因此說js處理ajax請求的方式是異步的。面試

總而言之,檢查調用棧是否爲空,以及肯定把哪一個異步任務加入調用棧的這個過程就是事件循環,而js實現異步的核心就是事件循環。ajax

一次事件循環的步驟包括:編程

  1. 主線程在執行代碼的時候,遇到異步任務會將它添加到一個事件隊列中(能夠理解爲一個數組),而後繼續執行下面的代碼,直到同步代碼執行完,而後執行步驟2
  2. 檢查事件隊列是否爲空,非空執行步驟3,爲空則繼續執行步驟2
  3. 取出事件隊列中的第一個放到調用棧,而後主線程執行調用棧的任務,再執行步驟4
  4. 執行視圖更新,而後回到步驟2

這就是事件循環api

先看一段代碼,理解一下:(面試題哦)數組

console.log('start')

setTimeout(function() {
  console.log('setTimeout')
}, 0)

Promise.resolve().then(function() {
  console.log('promise1')
}).then(function() {
  console.log('promise2')
})

console.log('end')

打印臺輸出的log順序是什麼?結合上面的步驟分析一下promise

Event Loop

最後的結果是:瀏覽器

start
end
promise1
pormise2
setTimeout

參考資料

Event Loop

相關文章
相關標籤/搜索