[Medium] LeetCode JS 30 - 2627. Debounce (手寫防抖函式)
2024年3月8日
💎 加入 E+ 成長計畫 與超過 500+ 位軟體工程師一同在社群中成長,並且獲得更多的軟體工程學習資源
LeetCode 30 Days of JavaScript
本題來自 LeetCode 的 30 天 JacaScript 挑戰
題目描述
請實作一個函式,該函式會接收另一個函式做為參數 fn
,並且接收一個以毫秒為單位的時間 t
,並回傳該函式的防抖 (debounce) 後版本。防抖是指,在函式執行被延遲了 t
毫秒內,如果該函式再次被呼叫,原本的執行將會被取消。
例如,假設 t = 50ms
,函式分別在 30ms
、60ms
和 100ms
時呼叫。前兩個函式呼叫將被取消,第三個函式呼叫將在 150ms
執 行。如果改為 t = 35ms
,則第一個呼叫將被取消,第二個呼叫將在 95ms
執行,第三個呼叫將在 135ms
執行。
上圖展示了防抖函式是如何轉換事件的。其中,每個矩形表示 100ms,防抖時間為 400ms。每種顏色代表一組不同的輸入。
請在不使用 lodash 的 _.debounce()
函式的前提下完成實作。
// 輸入
t = 50
calls = [
{“t”:50,輸入:[1]},
{“t”:75,輸入:[2]}
]
// 輸出
[{"t": 125, inputs: [2]}]
// 解釋
let start = Date.now();
function log(...inputs) {
console.log([Date.now() - start, inputs ])
}
const dlog = debounce(log, 50);
setTimeout(() => dlog(1), 50);
setTimeout(() => dlog(2), 75);
第一次呼叫被第二次呼叫取消,因為第二次呼叫發生在 100ms 之前
第二次呼叫延遲 50ms,在 125ms 執行,輸入為(2)。
本題解答
以下是本題的解答,詳細解題思路可以在 E+ 成長計畫看到。如果想練習更多題目,推薦可以到 GreatFrontEnd 上練習
解法
function debounce(fn, t) {
let timerId;
return function (...args) {
clearTimeout(timerId);
timerId = setTimeout(() => {
fn(...args);
}, t);
};
}