2.5 Event loop

單線程(single threaded)

首先,我們要知道 JavaScript 是單線程(single threaded runtime)的程式語言,所有的程式碼片段都會在堆疊中(stack)被執行,而且一次只會執行一個程式碼片段(one thing at a time)。

堆疊(stack)

在 JavaScript 中的執行堆疊(called stack)會記錄目前執行到程式的哪個部分,如果進入了某一個函式(step into),便把這個函式添加到堆疊(stack)當中的最上方;如果在函式中執行了 return ,則會將此函式從堆疊(stack)的最上方中抽離(pop off)。

以下面的程式碼為例:

function b() {
}

function a() {
  b()
}

a()

當我們在執行 JavaScript 的函式時,首先進入 stack 的會是這個檔案中全域執行環境的程式;接著 a 會被呼叫(invoke)因此進入堆疊(stack)的最上方;在 a 中會呼叫 b( ) 因此 b( ) 會進入堆疊(stack)的最上方。

JavaScript如何執行非同步事件(asynchronous callback)

  1. 首先判斷JS是同步還是異步,同步就進入主線程運行,異步就進入event table

  2. 異步任務在event table中註冊事件,當滿足觸發條件後(觸發條件可能是延時也可能是ajax回調),被推入event queue

  3. 同步任務進入主線程後一直執行,直到主線程空閒時,才會去event queue中查看是否有可執行的異步任務,如果有就推入主線程中

/*Copy from JavaScript: Understanding the weird part*/
function waitThreeSeconds(){
 var ms = 3000 + new Date().getTime();
 while(new Date() < ms){}
 console.log("finished function");
}

function clickHandler(){
 console.log("click event!");
}

document.addEventListener('click', clickHandler);
console.log("started execution");
waitThreeSeconds();
console.log("finished execution");

event loop 的作用是去監控堆疊(call stack)和工作佇列(task queue),當堆疊當中沒有執行項目的時候,便把佇列中的內容拉到堆疊中去執行。

Last updated