Throttle

MISC

既然都寫了 Debounce,那也來把概念很類似的 Throttle 也補上好了。
如果讀者兩個都還不太熟悉的話,建議從 Debounce 讀起。


什麼是 Throttle ?

跟 Debounce 的主要目的一樣是為了避免反覆密集的件觸發事。
就如同字面上的節流閥 (Throttle),每過一段時間只會觸發一次。不像 Debounce 是連續觸發好幾次都沒有意義,Debounce 只有最後一次在一段時間過後被執行。


常見應用

  • 觸發按鈕:
    特別像是會打出 request 的按鈕,但我覺得更好的作法是發 request 時讓按鈕進入 loading 或 disabled 狀態,結束後再切換回來。
  • 畫面滾動”時”的運算:
    例如滾動到特定高度時切換元素顯示與否、動畫播放等等。
  • 視窗大小變動:
    類似於上一點,但主要是監控目標是 resize 事件。

實作方式

傳入參數:

  1. func:欲執行的函式。
  2. ms:時間參數,用來設定觸發的間距。
// 實作
// 跟 debounce 一樣先用閉包先將計時器、函式、時間保存起來。
const throttle = (func, ms) => {
// 這次會將 timer id(註1) 移除,用來判斷是否超過計時,
// 所以先將 id 設為 null,作為判斷不存在的依據。
let timer = null;

return (...arg) => {
// id 存在,不動作。
if (timer !== null) return;

// id 不存在,執行函示
func(...arg);

// 設定間隔
timer = setTimeout(() => {
// 倒數完畢,移除 id。
timer = null;
}, ms);
}
}

註 1:
Timer ID 是用 setTimeoutsetInterval 的回傳值,也是用來識別 timer 的獨特 id。

Comments