前言

昨天提到了JavaScript可以利用「並行的方式」去做到非同步這件事情,而關於這到底是怎麼辦到的,就是今天的主題,然後今天主要的內容都是以這個影片為基礎=> 所以說 event loop 到底是什麼玩意兒?| Philip Roberts | JSConf EU,這影片對於JavaScript如何進行非同步的操作講得很清楚,推薦看。

出自影片的圖:

而以下是我看完影片,研究之後的自己見解。

Call Stack

每段程式的執行都會有call stack,可以用來紀錄執行的順序,只要函式在呼叫的時候,就會把它丟進去最下面,後面進來的就會再疊上去,而當函式處理完之後,再從最上面去拿走,這是一種後進先出的概念。

可以想像成一個洋芋片罐,最先放進去的洋芋片,會在洋芋片罐的最下方,當洋芋片都放完要拿的時候,先拿的那片洋芋片就會是洋芋片罐最上方的那個洋芋片。

之前有提到說JavaScript只有一個執行緒,所以不能做很多事情,其實是因為只有一個Call Stack,因此一次只能做一件事情。

Web Apis

意思是瀏覽器所提供的 api,我覺得最簡單的話,setTimeout其實就一種 Web Apis,專門做網頁計時器的功能,setTimeout它主要的核心其實就是非同步的概念,它會延遲的特性註定會跟同步不合,要是在同步延遲的話,就一定要一直等在那邊,直接延遲結束才能繼續下去。

所以在呼叫 Web APIs 時,很常會使用非同步的方式,我呼叫一個請求,但我不一定要馬上得到回覆。

Callback Queue

我自己把它當作一個等待排隊的地方,它跟Call Stack特性有點不一樣,是一個先進先出的概念,但這也蠻合理的,想像一下先進去排隊的人,因為他比要早去排隊,所以理所當然可以先結束排隊的這個狀態,非常合理。

為什麼有這個的存在,是因為不可能永遠一次只處理一個callback funtion,當有很多個callback funtion已經丟到Call Stack,時間先結束的就會先丟到Callback Queue等待排隊。

Event Loop

JavaScript執行非同步的方式,會使用到非同步的callback,假如有很多個,這些很多個的callback funtion就會進去到Callback Queue排隊,然後在執行階段的時候,會去判斷現在的callback裡面有沒有東西,當callback是空的時候,Callback Queue排隊的東西就會被丟進去,一次只能一個。

所以說,這也是一種一次做一件事情的方式,也是JavaScript如何使用並行的方式來執行非同步。

而因為非同步的東西會通通給丟去排隊的原因,所以非同步的函式永遠都會比同步的慢,同步的函式在執行call stack時就會把它結束掉,不會有進去到Callback Queue的機會。

總結

而關於JavaScript難道永遠就只能單執行緒,沒有例外嗎?
研究過後,有一種新的技術,它叫做Web Workers,據說是可以使用到其他的執行緒,不過我個人還沒有使用過,有興趣的可以依據這個關鍵字研究看看。

雖然非同步要用到callback,但之前要提到會有很可怕的callback hell問題,所以關於非同步的用法,JavaScript之後有一種更好的寫法,叫做promise,這個就是下一次要講的主題,我們明天見。

reference

[1] The event loop
[2] 異步程式設計與事件迴圈
[3] JavaScript 中的同步與非同步(上):先成為 callback 大師吧!
[4] JS 原力覺醒 Day13 - Event Queue & Event Loop 、Event Table
[5] Javascript 非同步 & Event Loop!10 分鐘輕鬆圖解學習!