1. 程式人生 > 實用技巧 >簡述 JavaScript 的執行機制

簡述 JavaScript 的執行機制

一、單執行緒

為了解決這個問題,防止下一個任務等待上一個任務等待太長的時間,所以提出了 Web Worker標準,允許 JS 建立多個執行緒,於是JS出現了同步非同步 ,非同步就是可以同時進行多個任務,這樣,大大的提高了我們程式碼的執行效率

栗子:

列印結果為:

(一) 同步任務

  • 同步任務都在主執行緒上執行,形成一個執行棧

(二)非同步任務

  • JS的非同步通過回撥函式來實現,一般而言,非同步任務有三種類型
  1. 普通事件: click事件 ,resize事件等
  2. 資源載入,如load,error等
  3. 定時器,包括 setInterval 和setTimeout等
  • 同步任務是放到啊主執行緒的執行棧中,非同步任務相關回調函式是放到任務佇列(訊息佇列)中

二、JS執行機制

三、事件迴圈 (event loop)

遇到多個任務的時候,JS是如何去進行處理的呢
所有的非同步任務都要放到任務佇列中去嗎?或者誰放在前面,誰放在後面呢?這時候就引入JS的非同步程序進行處理

  1. 先執行console.log(1) 列印 1

  2. 然後將 document.onclick 提交給非同步程序處理,決定是否寫入任務佇列中,只有點選了才會把回撥函式的非同步任務就放到任務佇列中去,如果不點選就不寫入到任務佇列中去

  3. 再執行console.log(2) 列印2

  4. 將setTimeout提交給非同步程序進行處理,只要3秒時間到了,才會把非同步回撥寫到任務佇列中去,只是寫入,尚未執行,要等到所有的同步任務都結束了才去執行

  5. 在沒有執行點選事件的時候,結果為1,2,3

  6. 如果在3秒之前就點選的話,那麼就會先執行點選事件的回撥函式

  7. 假設在3秒之前沒有進行,那麼當定時器的任務執行完之後,就把任務佇列中清空,但是同步任務會反覆檢視任務佇列中是否還有任務,如果此時執行點選事件的話,又會把點選事件的回撥函式放入到任務佇列中去執行,當執行完後又會清空,此時如果再次點選的話,又會把點選的回撥放到佇列中去執行

上圖理解:


總結:
由於主執行緒不斷的重複獲取任務,執行任務,再獲取任務,再執行任務,所有這種機制就被稱為 事件迴圈 (event loop)