Event-loop事件循環

Event-loop 事件循環

首先來看一段代碼javascript

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()

運行結果是先輸出1,而後大概好幾秒(大於一秒)之後依次輸出3,2java

setTimeout(() => {
  console.log('2')
}, 1000)

但是上邊這裏明明寫了定時器一秒後輸出字符串2啊,爲何過了很久才輸出呢?這裏就會引起思考,js究竟是怎麼執行的git


什麼是JS事件循環

先來一張經典圖
github

咱們都知道JS是單線程的,因此在它的stack(執行棧)裏面任務是排隊執行的,這裏咱們在回頭看開始的代碼瀏覽器

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()

當調用fn()的時候,就會把fn這個函數放到stack中去。執行步驟分如下幾步多線程

第一步:執行console.log('1')

第二步:執行到setTimeout 的時候,由於咱們都知道setTimeout是異步操做,這裏不可能說我js停下來等你1秒,這樣頁面就卡死在那裏了。異步

這裏在回過頭來看上面那Event-loop
函數

注:js是單線程,但js是運行在瀏覽器中的,瀏覽器是多線程的,這一點要搞清楚

當咱們運行到setTimeout這裏時,爲了避免阻塞頁面,瀏覽器會在開一個線程來處理異步的操做,也就是上圖紅框框部分。而後js會略過setTimeout,繼續執行下面for循環的代碼。
當一秒鐘以後setTimeout執行完畢,就會將結果放如到callback queue(回調隊列中等待調用),等待stack中的任務執行完畢後來調用它,因此一開始fn()函數的執行結果是1,3,2,、不是1,2,3.就是由於異步的操做被放在了callback queue中,等待stack中的執行完纔會去找它。oop

如今咱們搞明白了爲何結果是1,3,2 而不是1,2,3,以後還有一個問題就是爲何setTimeout明明寫的是1秒以後在控制檯打印出'2'來,爲何實際體驗中要好幾秒以後呢。緣由就在如下這部分代碼中post

for (let i = 0; i < 9999999999; i++) {
    aa = i
  }
  if (aa = 9999999998) {
    console.log('3')
  }

緣由就是這部分for循環的代碼執行過程超過了1秒。而這個for循環是放在stack裏面的。它執行不完就不會去callback queue裏面找東西,因此咱們看到的最終結果就是

先打印'1'出來 而後等幾秒後(這個隨電腦配置不一樣,時間長短不同),在打印出'2' 最後纔會打印出'3'
相關文章
相關標籤/搜索