2016年1月5日

[筆記] 談談JavaScript中的asynchronous和event queue


這篇文章我們來簡單談談JavaScript中的asynchronous和event queue的特性。

synchronous vs. asynchronous


synchronous指的是one at a time,也就是程式會逐列執行,一次執行一列;asynchronous多了一個a,指的就是more than one at a time,也就是程式在執行的時候會同時執行不只一列的程式碼。

JavaScript是synchronous在執行的


基本上JavaScript在執行程式的時候是synchronous的,也就是一次只會執行一列,逐行執行,那麼我們會進一步好奇,如果程式是逐行執行,那為什麼它可以監控瀏覽器的一些事件(event)呢?像是偵測滑鼠的點擊、滑動等等這類的非同步呼叫(asynchronous callback)。

首先我們不能忽略的一點是,JavaScript Engine只是在瀏覽網頁過程中的其中一個部分,另外還包含許多其它的部分,像是rendering engine和http request,也就是說,整個網頁在執行的過程中可以是非同步(asynchronous)的,但是單就JavaScript Engine來說,它還是同步(synchronous)逐行執行的

圖片截自:[Udemy] JavaScript: Understanding the weird parts


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


在前幾篇文章中有提過execution context的概念,在JavaScript執行asynchronous callback的過程是這樣的,它會先把所有的execution context的內容執行完畢後,才去執行"event queue",event queue裡面就包含像是滑鼠點擊或是http request的內容。

JavaScript Engine會先把execution context的內容執行完畢,接著才去執行"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");

在這個例子中,我們先建立一個函式waitThreeSeconds,這個函式會讓網頁等待3秒後出現"finished function"的字串,另外我們也添加了一個EventListener,當我點擊滑鼠時,就會出現"click event"的字串產生。

在我們執行上述程式碼的過程中,我們會先點擊滑鼠,然後讓網頁自然運作,最後來看console.log回應我們的訊息。



從上面的例子中我們可以發現,JavaScript Engine確實會先把execution context的內容執行完畢,接著才去執行"event queue"中的內容,所以雖然我們是在程式執行的一開始點擊滑鼠,但是"click event"的訊息卻是在"finished execution"出現後才顯示



→回到此系列文章目錄

資料來源

0 意見:

張貼留言