七個代替 setTimeout 的方案,讓定時任務更可靠
setTimeout是我們經常使用的定時器API,它允許我們延遲執行代碼。但在實際應用中,setTimeout存在一些局限性和潛在問題,比如精度不高、在頁面不活躍時可能被節流等。分享7種替代方案,讓我們的定時任務更加可靠和高效。
1. requestAnimationFrame
requestAnimationFrame主要用于執行動畫,它會在瀏覽器下一次重繪之前調用指定的回調函數。
function animateWithRAF(timestamp) {
// 執行動畫邏輯
requestAnimationFrame(animateWithRAF);
}
requestAnimationFrame(animateWithRAF);
優點:
- 與顯示器刷新率同步,通常為60fps
- 在不可見標簽頁中會暫停,節省資源
- 動畫更平滑
2. setInterval + clearInterval
對于需要重復執行的任務,setInterval比多個setTimeout更合適。
const intervalId = setInterval(() => {
console.log("每秒執行一次");
}, 1000);
// 停止定時器
// clearInterval(intervalId);
優點:
代碼更簡潔
更適合固定間隔的重復任務
3. requestIdleCallback
當瀏覽器空閑時執行低優先級任務,避免影響關鍵操作。
優點:
- 充分利用瀏覽器空閑時間
- 可以設置超時保證任務最終會執行
- 不阻塞主線程關鍵操作
4. Web Workers
將耗時任務移至后臺線程,避免阻塞主線程。
優點:
- 不阻塞UI線程
- 即使頁面不活躍也能繼續執行
- 適合計算密集型任務
5. Promise + async/await
用Promise包裝setTimeout,結合async/await使異步代碼更清晰。
優點:
- 代碼更清晰,避免回調地獄
- 更好的錯誤處理
- 便于鏈式組合多個異步操作
6. Web Animations API
對于動畫效果,Web Animations API提供了更高級的控制。
優點:
- 聲明式API,更易于理解
- 內置的暫停、恢復和控制功能
- 比CSS動畫和setTimeout更精確
7. Intersection Observer
當元素進入視口時執行代碼,比如延遲加載資源或觸發動畫。
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
console.log("元素進入視口");
// 執行需要的操作
}
});
});
observer.observe(document.querySelector('.lazy-load'));
優點:
- 無需手動計算元素位置
- 性能更好,避免滾動事件中大量計算
- 適合實現"按需執行"的場景