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