ECMAScript 之 Event Loop Model
由於 JavaScript 是 Single Thread 語言,由於其 Single Thread 特色,對於繁重的運算動作,就無法如 C# 使用 Multi Thread 解決,因此 Asynchronous 在 JavaScript 格外重要。
Browser 使用獨特的 Event Loop Model 實現 Asynchronous,要能徹底了解其背後運作原理,才能掌握 JavaScript 的 Asynchronous。
Single Thread
- One call stack
- One thing at a time
JavaScript 最大的特色就是 Runtime 為 Single Thread,也就是只有一個 Call Stack,因此一個時間只能做一件事情。
也由於只有一個 Thread,只要遇到 大量運算
,JavaScript 就會停住等待,因此使用者體驗就會不好。
C# 只要遇到
大量運算
,我們就會使用 Multi Thread,但 JavaScript 為 Single Thread,因此這招不能用在 JavaScript
因此 Browser 做了擴充,有些東西並不是由 JavaScript Runtime 實作,而是由 Browser 提供:
- DOM
- AJAX (XMLHttpRequest)
- setTimout()
也就是這三類 Browser 所提供的 API,屬於 Asynchronous 部分。
Event Loop Model
1 | console.log('Hello '); |
當 setTimeout()
為 0
秒時,會先執行 console.log('Sam')
還是 console.log('World ')
?
既然 dealy
0
秒,且寫在前面,應該先執行吧 ?
1 | concole.log('Hello '); |
當使用 AJAX 時,也會發現 console.log(' World')
會先執行。
會先執行 Stack 內的 function,直到 Stack 都執行完,才會執行 Event Loop,將 Callback Queue 內的 function 執行完。
1 | console.log('Hello '); |
console.log('Hello ')
進 Stack
- 清空 Stack,在 Console 顯示
Hello
1 | setTimeout(() => console.log('Sam'), 0); |
setTimeout()
進 Stack
- 清空 Stack,執行 Browser Thread 的
timer(0)
timer(0)
時間一到,將callback
塞進 Callback Queue
1 | console.log('World '); |
console.log('World ')
進 Stack
- 清空 Stack,在 Console 顯示
Hello World
- 所有 Synchronous Function 都已經執行完,開始執行 Event Loop
- 清空 Callback Queue,在 Console 顯示
Hello World Sam
Conclusion
- Asynchronous Function 會將 Callback 先塞進 Callback Queue,不會立即執行
- 等所有 Synchronous Function 都執行完,才開始執行 Event Loop 清空 Callback Queue 執行 Asynchronous Function
Reference
Philp Robers : What the heck is the event loop anyway ?