簡述 JavaScript 的執行機制
阿新 • • 發佈:2020-12-01
一、單執行緒
為了解決這個問題,防止下一個任務等待上一個任務等待太長的時間,所以提出了 Web Worker標準,允許 JS 建立多個執行緒,於是JS出現了
同步
和非同步
,非同步就是可以同時進行多個任務,這樣,大大的提高了我們程式碼的執行效率
栗子:
列印結果為:
(一) 同步任務
- 同步任務都在主執行緒上執行,形成一個執行棧
(二)非同步任務
- JS的非同步通過回撥函式來實現,一般而言,非同步任務有三種類型
- 普通事件: click事件 ,resize事件等
- 資源載入,如load,error等
- 定時器,包括 setInterval 和setTimeout等
- 同步任務是放到啊主執行緒的執行棧中,非同步任務相關回調函式是放到任務佇列(訊息佇列)中
二、JS執行機制
三、事件迴圈 (event loop)
遇到多個任務的時候,JS是如何去進行處理的呢
所有的非同步任務都要放到任務佇列中去嗎?或者誰放在前面,誰放在後面呢?這時候就引入JS的非同步程序進行處理
-
先執行console.log(1) 列印 1
-
然後將 document.onclick 提交給非同步程序處理,決定是否寫入任務佇列中,只有點選了才會把回撥函式的非同步任務就放到任務佇列中去,如果不點選就不寫入到任務佇列中去
-
再執行console.log(2) 列印2
-
將setTimeout提交給非同步程序進行處理,只要3秒時間到了,才會把非同步回撥寫到任務佇列中去,只是寫入,尚未執行,要等到所有的同步任務都結束了才去執行
-
在沒有執行點選事件的時候,結果為1,2,3
-
如果在3秒之前就點選的話,那麼就會先執行點選事件的回撥函式
-
假設在3秒之前沒有進行,那麼當定時器的任務執行完之後,就把任務佇列中清空,但是同步任務會反覆檢視任務佇列中是否還有任務,如果此時執行點選事件的話,又會把點選事件的回撥函式放入到任務佇列中去執行,當執行完後又會清空,此時如果再次點選的話,又會把點選的回撥放到佇列中去執行
上圖理解:
總結:
由於主執行緒不斷的重複獲取任務,執行任務,再獲取任務,再執行任務,所有這種機制就被稱為 事件迴圈 (event loop)