An Interest In:
Web News this Week
- April 18, 2024
- April 17, 2024
- April 16, 2024
- April 15, 2024
- April 14, 2024
- April 13, 2024
- April 12, 2024
Debounce
Debouncing is a technique used to control how many times we allow a function to be executed over time. When a JavaScript function is debounced with a wait time of X milliseconds, it must wait until after X milliseconds have elapsed since the debounced function was called. You almost certainly have encountered debouncing in your daily lives before when entering an elevator. Only after X duration of not pressing the "Door open" button (the debounced function not being called) will the elevator door actually close (the callback function is executed).
Implement a debounce function which accepts a callback function and a wait duration. Calling debounce() returns a function which has debounces invocations of the callback function following the behavior described above.
example:let i = 0;function increment() { i++;}const throttledIncrement = throttle(increment, 100);// t = 0: Call throttledIncrement(). i is now 1.throttledIncrement(); // i = 1// t = 50: Call throttledIncrement() again.// i is still 1 because 100ms have not passed.throttledIncrement(); // i = 1// t = 101: Call throttledIncrement() again. i is now 2.// i can be incremented because it has been more than 100ms// since the last throttledIncrement() call at t = 0.throttledIncrement(); // i = 2
Debounce, along with throttle, are among the most common front end interview questions; it's the front end equivalent of inverting a binary tree. Hence you should make sure that you are very familiar with the question.
Solution:
Given that there's a wait duration before the function can be invoked, we know that we will need a timer, and setTimeout is the first thing that comes to mind.
We will also need to return a function which wraps around the callback function parameter. This function needs to do a few things:
Debounce invocation
- It invokes the callback function only after a delay of
wait
. This is performed usingsetTimeout
. Since we might need to clear the timer if the debounced function is called again while there's a pending invocation, we need to retain a reference to atimeoutID
, which is the returned value ofsetTimeout
. - If the function is called again while there's a pending invocation, we should cancel existing timers and schedule a new timer for the delayed invocation with the full
wait
duration. We can cancel the timer viaclearTimeout(timeoutID)
.
- It invokes the callback function only after a delay of
Calls the callback function with the right parameters
Debounced functions are used like the original functions,
so we should forward the value of this and function
arguments when invoking the original callback functions.
You may be tempted to usefunc(...args)
but this will be
lost if callback functions are invoked that way. Hence we
have useFunction.prototype.apply()/Function.prototype.call()
which allows us to specifythis
as the first argument.
func.apply(thisArg, args)
func.call(thisArg, ...args)
/** * @callback func * @param {number} wait * @return {Function} */// debounce(func, wait) will returned a debounced function, which delays the invoke.export default function debounce(func, wait) { let timer = null; function debounced (...args) { const context = this; //retain a reference to this outside the setTimeout and pass it into func.apply as the 1st argument. if(timer) clearTimeout(timer); //If the function is called again while there's a pending invocation, we should cancel existing timers //schedule a new timer for the delayed invocation with the full wait duration. timer=setTimeout(()=>{ func.apply(context, args) }, wait) } return debounced // return arrow function}
More solutions
- return the arrow function
function debounce(func, wait) { let timer = null; // return the arrow function return (...args) => { if(timer) clearTimeout(timer); timer=setTimeout(()=>{ func(args); }, wait) }}/*TEST-------------------------------------------------- */function test (){ console.log('test') }// debouncedocument.onmousemove = function(){ test();}// debounceconst debouncedFn = debounce(test, 1000);document.onmousemove = function(){ debouncedFn();}
Original Link: https://dev.to/986913/debounce-1bja
Dev To
An online community for sharing and discovering great ideas, having debates, and making friendsMore About this Source Visit Dev To