異步編程當然少不了定時器了,常見的定時器函數有 setTimeout、setInterval、requestAnimationFrame。最常用的是setTimeout,很多人認為 setTimeout 是延時多久,那就應該是多久后執行。
其實這個觀點是錯誤的,因為 JS 是單線程執行的,如果前面的代碼影響了性能,就會導致 setTimeout 不會按期執行。當然了,可以通過代碼去修正 setTimeout,從而使定時器相對準確:
接下來看 setInterval,其實這個函數作用和 setTimeout 基本一致,只是該函數是每隔一段時間執行一次回調函數。
通常來說不建議使用 setInterval。第一,它和 setTimeout 一樣,不能保證在預期的時間執行任務。第二,它存在執行累積的問題,請看以下偽代碼
以上代碼在瀏覽器環境中,如果定時器執行過程中出現了耗時操作,多個回調函數會在耗時操作結束以后同時執行,這樣可能就會帶來性能上的問題。
如果有循環定時器的需求,其實完全可以通過 requestAnimationFrame 來實現:
首先 requestAnimationFrame 自帶函數節流功能,基本可以保證在 16.6 毫秒內只執行一次(不掉幀的情況下),并且該函數的延時效果是精確的,沒有其他定時器時間不準的問題,當然你也可以通過該函數來實現 setTimeout。