JavaScript單執行緒概念

螞蟻小編發表於2018-07-17

眾所周知,JavaScript是單執行緒的,由此可能會給初學者帶來很多疑惑。

比如為什麼ajax請求可以是非同步,setTimeout算不算是多執行緒。

首先看一段程式碼例項:

[JavaScript] 純文字檢視 複製程式碼執行程式碼
for (var index = 0; index < 100000; index++) {
  console.log(5);
}
setTimeout(function () { console.log("螞蟻部落") }, 5);

程式碼本意是在5ms後列印"螞蟻部落",但實際情況是,需要遠遠超過5ms時間後才會列印。

一.JavaScript是單執行緒:

JavaScript在執行過程中單執行緒的,那麼在特定時刻只能有唯一的特定程式碼在執行,並阻塞其他JavaScript程式碼。

瀏覽器是事件驅動(Event driven),這些事件可以源自JavaScript引擎當前執行的程式碼塊,如呼叫setTimeout新增一個任務,也可來自瀏覽器核心的其它執行緒,如介面元素滑鼠點選事件,定時器時間到達通知,非同步請求狀態變更通知等,這些事件的引起結果是對應事件處理函式進入JavaScript單執行緒佇列,排隊等待執行。

二.瀏覽器是多執行緒的:

雖然JavaScript是單執行緒的,但是瀏覽器是多執行緒的,下面瀏覽器幾個最基本執行緒:

(1).JavaScript引擎執行緒。

(2).介面渲染執行緒。

(3).瀏覽器事件觸發執行緒。

(4).Http請求執行緒。

setTimeout和setInterval計數器並不是由JavaScript執行緒實現,而是由瀏覽器實現。

看如下程式碼:

[JavaScript] 純文字檢視 複製程式碼執行程式碼
setTimeout(function () {
  console.log("螞蟻部落")
}, 5000);

程式碼會在5秒後列印"螞蟻部落"。當呼叫setTimeou方法之後,瀏覽器提供的執行緒開始進行計數,當5秒之後,將回撥函式放入JavaScript執行緒執行佇列,等待執行。雖然規定在5ms後將回撥函式放入佇列,無奈JavaScript執行緒中還有其他程式碼在執行。

三.ajax非同步請求:

ajax請求確實是非同步的,,不過這請求是由瀏覽器新開一個執行緒請求,當請求的狀態變更時,如果先前已設定回撥函式,此非同步執行緒就將事件處理函式放入JavaScript執行緒的處理佇列中等待處理,當任務被處理時,JavaScript引擎始終是單執行緒執行回撥函式。

相關文章