這篇文章我們來簡單談談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 意見:
張貼留言