Medium
Given a function fn and a time in milliseconds t, return a debounced version of that function.
A debounced function is a function whose execution is delayed by t milliseconds and whose execution is cancelled if it is called again within that window of time. The debounced function should also receive the passed parameters.
For example, let's say t = 50ms, and the function was called at 30ms, 60ms, and 100ms. The first 2 function calls would be cancelled, and the 3rd function call would be executed at 150ms. If instead t = 35ms, The 1st call would be cancelled, the 2nd would be executed at 95ms, and the 3rd would be executed at 135ms.
The above diagram shows how debounce will transform events. Each rectangle represents 100ms and the debounce time is 400ms. Each color represents a different set of inputs.
Please solve it without using lodash's _.debounce() function.
給定一個函數fn
和一個以毫秒為單位的時間t
,回傳該函數的去抖版本。
去抖函數(debounced function)是指其執行延遲「t」毫秒的函數,如果在該時間間隔再次呼叫函數,則其執行將被取消。 去抖函數也應該接收傳遞的參數。
例如,假設t = 50ms
,且該函數在30ms
、60ms
和100ms
時呼叫。 前 2 個函數呼叫將被取消,第 3 個函數呼叫將在「150ms」處執行。
如果改為t = 35ms
,則第一個呼叫將被取消,第二個呼叫將在95ms
執行,第三個呼叫將在135ms
執行。
上圖顯示了去抖將如何轉換事件。 每個矩形代表 100ms
,去抖時間為 400ms
。 每種顏色代表一組不同的輸入。
請在不使用 lodash函示庫 的 _.debounce()
方法下解決這個問題。
1.給定一個函數“fn”和一個以毫秒為單位的時間“t”,返回該函數的去抖版本。
function debounce(fn, t) {
return () => {
//調用邏輯
};
}
2.去抖函數是指其執行延遲“t”毫秒的函數,如果在該時間窗口內再次調用該函數,則其執行將被取消。
去抖函數還應該接收傳遞的參數。
如果在該時間窗口內再次調用該函數,則其執行將被取消。
-> 調用的時候,如果計時器存在應該清除計時器以取消調用fn
-> 外部作用域要宣告變數timer
來記憶 timeoutID,在內部引用setTimeout()把ID傳到timer
-> 在重置計時器之前應先清除原本的計時器,在setTimeout之前設置clearTimeout把舊的計時器清除。
function debounce(fn, t) {
let timer ;
return (...args) => {
clearTimeout(timer);
timer = setTimeout(()=>{fn(...args)},t);
};
}
let start = Date.now();
function log(...inputs) {
let log = [Date.now() - start, inputs];
//console.log(log); //[time, Array(inputs)]
console.log(`[${log[0]},[${log[1]}]]`);
}
test1
// 1. 執行`debounce`的時間間隔是50ms
const dlog = debounce(log, 50);
// 2. 在50ms 執行`dlog(1)`
setTimeout(() => dlog(1), 50);
//設置計時器A: 50毫秒後會調用fn(1)
// 3. 在75ms 執行`dlog(2)`
setTimeout(() => dlog(2), 75);
//清除計時器A
//設置定時器B: 再過50毫秒後調用fn(2)
//最後會在 125毫秒的時候打印log `[125, [2]]`
test2
// 1. 執行`debounce`的時間間隔是20ms
const dlog = debounce(log, 20);
// 2. 在50ms 執行`dlog(1)`
setTimeout(() => dlog(1), 50);
//設置計時器A: 20毫秒後會調用fn(1)
// 70ms時打印 [90,[1]]
// 3. 在100ms 執行`dlog(2)`
setTimeout(() => dlog(2), 100);
//設置定時器B: 再過20毫秒後調用fn(2)
// 120ms時打印 [136,[2]]
test3
// 1. 執行`debounce`的時間間隔是150ms
const dlog = debounce(log, 150);
// 2. 在50ms 執行`dlog(1,2)`
setTimeout(() => dlog(1,2), 50);
//設置計時器A: 150毫秒後會調用fn(1,2)
// 200ms時打印 [216,[1,2]]
// 3. 在300ms 執行`dlog(3,4)`
setTimeout(() => dlog(3,4), 300);
//設置定時器B: 再過150毫秒後調用fn(3,4)
setTimeout(() => dlog(5,6), 300);
//清除計時器B
//設置定時器C: 再過150毫秒後調用fn(5,6)
// 450ms時打印 [464,[5,6]]