基礎又艱深的用詞single thread / call stack / blocking / queue / event loop / setTimeOut 看影片學起來!
學過JS相信一定有聽過Event Loop,這邊記錄下我觀看所以說event loop到底是什麼玩意兒?| Philip Roberts | JSConf EU 這部影片的心得筆記,順便也將裡面提到的內容再做多一點延伸,一開始先針對Event loop會遇到的一些名詞作解釋
single thread(單一線程):
JavaScript是single thread language,代表的是只有一個call stack 和一個 memory heap,同時也表示他會執行完一段程式碼後再接續執行下一段程式碼(一次做一件事情)。
Call Stack(Last In, First Out)
是一種資料結構,紀錄依序堆疊尚未執行的程式碼,第一個被呼叫的會被放在底層,最後被呼叫的被放在頂層,並開始執行,因為他的LIFO特型,頂層的會先被執行,再依序往下執行。
如以下流程:
- 呼叫 eating() 函式
- 將 eating() 函式加入 Call Stack 中
- 進入 eating() 函式中的 eatLunch()
- 將 eatLunch() 放入 Call Stack 中(會放在 eating() 函式之上,因為LIFO)
- 開始執行最後放入的函式,也就是 eatLunch() ,並印出
pizza!
- 執行完 eatLunch()後,從 Call Stack 中移除,此時 Call Stack中剩下 eating()
- 往下執行完 eating() ,結束後同時從 Call Stack 中移除,此時 Call Stack 為空,可以接下去進行下一個動作了!
blocking阻塞
需要花時間完成的程式(如網路請求),且因JS是single thread,所以當這些速度較慢的request尚未執行完成時,主程式不能往下走,且不能執行其他操作,若想要有流暢的UI的話,這是不能發生的情形。
WebAPIs
JavaScript runtime一次只能做一件事情沒錯,但瀏覽器會提供許多APIs讓我們可以同時執行任務,並將透過APIs完成的任務放進Queue中,像是DOM、ajax 和本次主角setTimeOut。
callback queue / task queue( FIFO = First In, First Out)
暫存從WebAPIs傳送來的任務,等待event loop的調配,當call stack清空後,就會將callback queue 的任務依序傳送至call stack
這時候就要講到本次的重點了,JavaScript 、 callback queue、WebAPIs 與event loop的關係
event loop
查看stack 並查看task queue,如果stack是空的(一定要等到是清空的才可以往下執行),他會將task queue的第一個東西丟到stack上,並讓stack可以順利執行。
以下進行簡單的說明
1.從 js 中開始進行程式,並從第一行開始執行,放入stack中,再console出來
2.來到setTimeOut部分,一樣先放置stack中,接著瀏覽器就啟動計時器,同時表示呼叫setTimeOut完成,就把setTimeOut從 stack中移除。
3.此時stack是空的, js 就繼續往下執行console.log並印出JSConfEU,而此同時WebAPIs依舊在進行。
4.與此同時,WebAPIs的五秒也到了,但 WebAPIs 不能隨便將完成好的程式丟回stack中,這樣會導致整個程式碼的執行順序錯亂,所以基本上跑完任何 WebAPIs 後,都會將call back傳送至 callback quene中等待傳送。
5.此時就是Event loop的工作了,他確認stack沒有任何待執行程式後,就會將第一個送入callback queue的callback,傳送至stack中,也就是我們的function cb(),接下來再執行function cb()中的程式,也就是印出there。
6.執行完印出there整個function cb()就結束了,最後stack也被清空,從這邊也能看到,透過WebAPIs的協助,JS不用等到執行完setTimeOut才往下執行,而是同步進行的。
這時候可能會有人很好奇,那如果把setTimeOut的時間改為0秒呢?會不會console出來的順序是there在中間,答案是不會的!
因為不論你setTimeOut的時間設置多少,他一樣會經過WebAPIs再到callback queue中等待stack被清空,因此結果會是一樣的,以下我直接執行程式來示範,若還有疑問歡迎提出唷!
以下直接放神影片連結,裡面的動畫+模擬器真的很幫助了解整個原理!