JavaScript 核心 - Event Loop


Posted by ai86109 on 2020-09-30

前言

在講 event loop 之前,建議去看一下一個很有名介紹 event loop 的影片:What the heck is the event loop anyway?,說不定看完這部影片你也就會了,真的有可能拉。

倘若看完之後你還是不太懂,但至少再往下看文字的時候,你腦袋裡也比較會有圖像感,所以還是看一下摟!


JavaScript 是怎麼執行程式的?

JavaScript 是一個單執行緒的程式語言,代表他一次只做一件事

當他在逐行執行程式時,他會把他目前執行的東西放到 call stack 裡面

Call stack 是什麼?

Call stack 是執行堆疊,他可以記錄我們目前在程式中,執行到哪個位置

假設我們有一段程式,裡面有一個 function,function 裡面有一個 console.log 會印出 hello,以及最後我們有一個 call 這個 function 的段落

function sayHello() {
  console.log('hello')
}

sayHello()

所以當我們執行這個程式,跑到 call function 的部分時,sayHello() 會被放到 call stack 裡面,接著進入 function,把 console.log('hello') 放到 call stack,印出 hello,執行完退出退出,全部執行完 call stack 也就會清空。

但依照這樣的模式,如果我們中間執行的東西很慢(比如說去跟其他網站要資料),那整個程式就會卡在那裡,等到這個東西處理完才會繼續跑之後的程式,因為前面說過 JavaScript 一次只能做一件事。

這樣就會造成使用者體驗不佳的情況。


那就用非同步吧

為了解決這個情況,就要使用到非同步,程式一樣堆疊到 call stack,回傳結果後退出,這邊的機制跟前面說的都一樣。

當我們跑到非同步事件,像是 ajax, setTimeout 這些有 callback function 的事件時,會被呼叫之後進入 call stack,以 setTimeout(cb, 100) 為例,他在 call stack 中執行,然後在瀏覽器設定一個計時器,這個事件便執行完畢,退出 call stack。

接著,100 毫秒過後瀏覽器發現時間到了,便會將 cb 推到一個叫 task queue(任務佇列,或稱 callback queue)的地方排隊。

剛剛說到這些非同步的事件,會在執行完畢(例如:setTimeout 是在瀏覽器設定一個計時器)後,就從 call stack 中退出來,並不會等到計時器跑完才退出,因此之後的程式碼就不會被卡住,可以繼續被執行。

那這些 task queue 裡面的事件什麼時候可以被執行?

就是當 call stack 被清空之後。

當 call stack 被清空之後,task queue 裡面的事件就會被依序推回 call stack。

這個偵測到 call stack 是空的,便把 task queue 內的事件推回給 call stack 的機制就稱為 event loop。


簡單來說 event loop 就是這樣,理解之後就可以對非同步有更進一步的理解,相關非同步的知識,可以參考:JavaScript 中的同步與非同步(上):先成為 callback 大師吧!


#Event Loop #javascript #call stack #task queue #callback queue







Related Posts

轉職前端工程師之路 Day1

轉職前端工程師之路 Day1

Node.appendChild() vs. Element.append()

Node.appendChild() vs. Element.append()

[Week 2] JavaScript - 變數、陣列、物件、== 與 ===

[Week 2] JavaScript - 變數、陣列、物件、== 與 ===


Comments