本篇內容整理 Philip Roberts 演講影片, 圖片擷取影片片段
https://www.youtube.com/watch?time_continue=195&v=8aGhZQkoFbQ&feature=emb_logo
Single thread
Javascript 是個單線程(single thread)的語言, 也就是單一時間點只能執行一個指令, 無法執行多個
Stack
程式語言在執行時, 會按照執行順序把內容放到 stack
比如下圖, 首先進入 stack 是全域程式環境 main(), 接著是 printSquare(4), printSquare 裡面呼叫 square(n), 因此 square(n) 接著放進 stack, 以此類推
而 stack 行為是 First in last out, 執行順序
multiply(n, n) -> square(n)->printSquare(4)->main()
執行後 stack 會跟著清空
Blocking
當碰到需要等待一段時間程式碼時, 像是卡住一段時間, 這種現象就做 “blocking”. 如下程式碼
// pseudo code
var foo = $.getSync('//foo.com')
var bar = $.getSync('//bar.com')
var qux = $.getSync('//qux.com')
console.log(foo)
console.log(bar)
console.log(qux)
執行 getSync() 時需要等待些時間, 這段時間瀏覽器無法做任何動作, 必須等到當下程式碼結束才能執行下個動作
非同步處理 (Async Callback)
為了解決上面 block 問題, 可以透過非同步處理方式搭配 callback
console.log('hi')
setTimeout(function () {
console.log('there')
}, 5000)
console.log('JSConfEU')
那 setTimeout() 被暫時放在哪邊呢 ?
Concurrency and Event Loop
Javascript 在同個時間只能執行一件事, 不過瀏覽器提供許多 API, 讓我們可以用 event loop 搭配非同步方法同時 (concurrent) 處理許多事
在上面 Async 裡說到用 setTimeout 方式實行非同步, setTimeout 是瀏覽器提供的 API
當 stack 中沒有其他指令, 這時輪到 event loop 功能登場, 它會把 task queue 中第一個指令給 stack (queue 跟 stack 相反, First in first out)
setTimeout 0
假設上面 case 換成設定 setTimeout 0 會發生什麼事呢 ?
console.log('hi')
setTimeout(function () {
console.log('there')
}, 0)
console.log('JSConfEU')
預想上 timeout 0 表示 0 秒後啟動, 執行應該是 hi -> there -> JSConfEU
但依照上面邏輯, 即便我們只是等 0 秒, cb 依樣會放到 task queue 中, 等到 stack 指令執行完才會執行 setTimeout 裡的內容, 所以正確執行為
hi -> JSConfEU -> there