函數防抖的應用場景
連續的事件,只需觸發一次回調的場景有:
- 搜索框搜索輸入。只需用戶最後一次輸入完,再發送請求
- 手機號、郵箱驗證輸入檢測
- 窗口大小Resize。只需窗口調整完成後,計算窗口大小。防止重複渲染。
實現原理
函數防抖(debounce)
函數防抖的簡單實現:
const _.debounce = (func, wait) => {
let timer;
return () => {
clearTimeout(timer);
timer = setTimeout(func, wait);
};
};
函數防抖在執行目標方法時,會等待一段時間。當又執行相同方法時,若前一個定時任務未執行完,則 clear
掉定時任務,重新定時。
函數節流的應用場景
每間隔一段時間執行一次回調的場景有:
- 滾動加載,加載更多或滾到底部監聽
- 谷歌搜索框,搜索聯想功能
- 高頻點擊提交,表單重複提交
函數節流(throttle)
1)函數節流的 setTimeout
版簡單實現
const _.throttle = (func, wait) => {
let timer;
return () => {
if (timer) {
return;
}
timer = setTimeout(() => {
func();
timer = null;
}, wait);
};
};
函數節流的目的,是爲了限制函數一段時間內只能執行一次。因此,通過使用定時任務,延時方法執行。在延時的時間內,方法若被觸發,則直接退出方法。從而,實現函數一段時間內只執行一次。
2)函數節流的時間戳版簡單實現
根據函數節流的原理,我們也可以不依賴 setTimeout
實現函數節流。
const throttle = (func, wait) => {
let last = 0;
return () => {
const current_time = +new Date();
if (current_time - last > wait) {
func.apply(this, arguments);
last = +new Date();
}
};
};
其實現原理,通過比對上一次執行時間與本次執行時間的時間差與間隔時間的大小關係,來判斷是否執行函數。若時間差大於間隔時間,則立刻執行一次函數。並更新上一次執行時間。
異同比較
相同點:
- 都可以通過使用
setTimeout
實現。 - 目的都是,降低迴調執行頻率。節省計算資源。
不同點:
- 函數防抖,在一段連續操作結束後,處理回調,利用 clearTimeout 和 setTimeout 實現。函數節流,在一段連續操作中,每一段時間只執行一次,頻率較高的事件中使用來提高性能。
- 函數防抖關注一定時間連續觸發,只在最後執行一次,而函數節流側重於一段時間內只執行一次。。