Debounce 裝飾器
debounce(f, ms)
裝飾器的結果是一個包裝函式,它會暫停對 f
的呼叫,直到 ms
毫秒的非活動時間(沒有呼叫、「冷卻時間」),然後使用最新的引數呼叫 f
一次。
換句話說,debounce
就像一位秘書,負責接「電話」,並等待安靜的毫秒數達到 ms
。然後才會將最新的通話資訊轉達給「老闆」(呼叫實際的 f
)。
例如,我們有一個函式 f
,並將其替換為 f = debounce(f, 1000)
。
然後,如果在 0 毫秒、200 毫秒和 500 毫秒呼叫包裝函式,接著沒有呼叫,則實際的 f
將只會在 1500 毫秒時呼叫一次。也就是說:在最後一次呼叫的冷卻時間 1000 毫秒後。
…而且它會取得最後一次呼叫的引數,其他呼叫都會被忽略。
以下是其程式碼(使用 Lodash 函式庫 中的 debounce 裝飾器)
let f = _.debounce(alert, 1000);
f("a");
setTimeout( () => f("b"), 200);
setTimeout( () => f("c"), 500);
// debounced function waits 1000ms after the last call and then runs: alert("c")
現在舉一個實際的例子。假設使用者輸入一些內容,我們希望在輸入完成時向伺服器發送請求。
沒有必要在輸入每個字元時都發送請求。我們希望等待,然後處理整個結果。
在網路瀏覽器中,我們可以設定一個事件處理常式,也就是在輸入欄位每次變更時呼叫的函式。通常,事件處理常式會非常頻繁地呼叫,也就是在輸入每個按鍵時。但是,如果我們使用 1000 毫秒對其進行 debounce
,則它只會在最後一次輸入後 1000 毫秒呼叫一次。
在此範例中,處理常式會將結果放入下方的方塊中,請試試看
看到了嗎?第二個輸入呼叫了 debounced 函式,因此其內容在最後一次輸入後 1000 毫秒才處理。
因此,debounce
是處理一系列事件的絕佳方法:無論是按鍵序列、滑鼠移動或其他事件。
它會在最後一次呼叫後等待指定的時間,然後執行其函式,該函式可以處理結果。
任務是實作 debounce
裝飾器。
提示:如果你仔細想想,這只有幾行而已 :)
function debounce(func, ms) {
let timeout;
return function() {
clearTimeout(timeout);
timeout = setTimeout(() => func.apply(this, arguments), ms);
};
}
呼叫 debounce
會傳回一個包裝器。呼叫時,它會在指定的 ms
後排程原始函式呼叫,並取消前一個此類逾時。