[JavaScript] 神奇的 setTimeout

Juju 的自學筆記
3 min readDec 1, 2020

--

在Alphacamp的課程裡看到了一個乍看之下覺得很無法理解的現象:

因為 JavaScript 是單線執行的(照順序一次做一件事),會覺得程式應該先執行第 1 行的 setTimeout,再執行到第 3 行的 console.log 呀~

可是看右邊 console 跑出來的結果,竟然是先出現第 3 行的 ‘Hello!’ 才出現第 1 行的 ‘delay 0 sec’….

就算 setTimeout 是用來等待的,但設 0 秒怎麼不是立刻就出現?

看了助教提供的一個影片後有了解多了!

用這篇文章記錄下我的筆記,讓以後忘記可以回來看看。

影片名:What the heck is the event loop anyway?

看完整個影片後就了解多了!

原來是瀏覽器有為了符合使用者體驗的貼心小設計在背後運做,讓瀏覽器盡可能不要卡住。

下面節圖是我從影片中弄懂這個概念的片段:

左上是 JavaScript 程式碼,左下是印出 console.log 的 console。

右邊的圖很重要,讓我整個瞭解了這個運作模式。

名詞解釋

stack :
JavaScript 單線運作的地方。

webapis:
web api 會在這裡等待做完,完成後若有 callback function, callback function 就會被放到 task queue,等被 event loop 送回 stack,去執行 callback function。

task queue / callback queue:
web api 的 callback function 被放到這裡等待,直到 event loop 確定 stack 空了,會依照先來的先走的順序丟回 stack。

event loop:
工作是看 stack 空了沒,空了就把 task queue 裡的東西依序丟到 stack。
丟的順序是先來的先走。
如果 stack 不是空的,event loop 不會做事。

setTimeout

setTimeout是 web api 的一種,會直接被 stack 略過,放到 webapis 那格等待 web api 做完事,如果有 callback function 會被放到 task queue。

setTimeout 的秒數其實是至少停幾秒,但不是確切幾秒,因為你還要考量到 web api 處理的時間。

如果不希望被會花費時間的動作卡住,就可以利用 setTimeout,在 function 內做事。

因為只要遇到 setTimeout,就會被丟到 webapis,不會卡住 stack。

只要是 web api ,都會直接被 stack 略過,丟到 webapis 處理。

所以我就解惑啦!

不管你 setTimeout 幾秒,不管你 setTimeout 放多前面,你都要等所有 stack 裡的事情做完,才會被輪到。

所以會先看到第 3 行的 ‘Hello!’ ,再第 1 行的 ‘delay 0 sec’ 就合情合理啦!

--

--

No responses yet