節流 Throttling
節流限制了一個函數可以在短時間內被調用的次數。可以這樣形容:在一毫秒內最多執行此函數 1 次。
Throttling enforces a maximum number of times a function can be called over time. As in "execute this function at most once every 100 milliseconds."
再換句話說:
節流會忽略在短時間內高頻發生的事件,只按照計劃好的頻率觸發。
//fn 要執行的函數
//delay 計劃好的執行間隔
//返回一個函數
function throttled(fn, delay) {
let lastCall = 0;//初始化lastCall
return function (...args) {
const now = (new Date).getTime();//當函數被運行,獲取當前時間
if (now - lastCall < delay) {
//這裏(now - lastCall)就是間隔時間
return;//如果間隔時間小於計劃好的執行間隔,什麼也不做。
}
lastCall = now; //更新lastCall
return fn(...args);
}
}
防抖 Debouncing
防抖確保了一個函數只有在一個固定時間段內沒有被調用過後,纔會再次被調用。可以這樣形容:比如說只有在 1 毫秒過後,才允許執行這個函數。
Debouncing enforces that a function not be called again until a certain amount of time has passed without it being called. As in "execute this function only if 100 milliseconds have passed without it being called."
再換句話說:
防抖會等待事件不再高頻發生,再觸發。
//fn 要執行的函數
//delay 計劃好的等待時間
//返回一個函數
function debounced(delay, fn) {
let timerId;
return function (...args) {
if (timerId) {//如果正在一個timeout中
clearTimeout(timerId);//中斷timeout,不會發生setTimeout的回調函數
}
timerId = setTimeout(() => {//開始新的timeout
fn(...args);
timerId = null;
}, delay);
}
}
結論
節流在我們不關心函數參數是什麼的時候比較有用,比如鼠標移動,滾輪事件,我們在乎的是操作的頻率。
防抖在我們關心高頻事件發生過後,得到的那個結果的時候,比較有用,比如用戶迅速輸入完一串用戶名,對其進行查重的結果。
這個網站 很好的可視化了節流與防抖。
參考信息
The Difference Between Throttling and Debouncing
Understanding Throttling and Debouncing