你知道 JavaScript 的 setTimeout() 與 setInterval() 有拖延症嗎?
如果要在前端等待特定時間後某些工作,或者定期執行某些工作,都是用 setTimeout()
與 setInterval()
達成需求。
不過使用這 2 個函式的最大誤區是認為它會準時執行⋯⋯。
「 是的,它們不保證可以準時在特定時間後執行,或者定期執行! 」
所以千萬別以為寫了個 60 秒後執行的工作,它就會在 60 秒後準時執行,如果它所在的分頁是 inactive 分頁(也就是使用者沒在使用的分頁),那很有可能會拖得比 60 秒更久!
這個不準時的特性就導致 1 個問題,那就是要在網頁用 JavaScript 做到準時的計時器或者倒數計時器是相當難的 1 件事,頂多只能逼近,無法 100% 準時。
所以如果你有功能對於執行時間精準度相當要求,那可能要考慮用其他手段達成。
MDN 文件中也羅列幾種情況可能導致 setTimeout()
與 setInterval()
不準時:
- 巢狀(nested)呼叫 s
etTimeout()
的情況,在這種情況之下,如果呼叫超過 4 次,第 5 次起瀏覽器會強制設定最小延遲 4ms - Inactive 分頁, Chrome 與 FireFox Desktop 對於 Inactive 分頁都有最小 1s 的延遲設定,所以對 Inactive 分頁來說
setTimeout()
就算設定小於 1s 也沒用⋯⋯ (但如果分頁正在播放音效,是有可能擺脫這個限制,還是老話一句,各家瀏覽器實作不一樣⋯⋯) - FireFox 會強制對某些被認為是 tracking scripts (追蹤使用者行為的 scripts)設定延遲
- 如果你的網頁正在忙其他工作,也可能導致
setTimeout()
與setInterval()
不準時 - FireFox 在網頁還在 loading 的狀態下,也會延遲
setTimout()
初次執行
所以有人來問你怎麼 setTimeout()
, setInterval()
為什麼沒有準時執行時,請告訴他/她瀏覽器也有拖延症是很正常的事,並且給他/她 MDN 文件拜讀一下!