Created
June 16, 2023 05:20
-
-
Save hrishikeshs/29790285797def367ece0d573921940a to your computer and use it in GitHub Desktop.
debounce and throttle implementations in plain english
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* It has somehow become very fashionable to ask candidates in frontend engineering interviews | |
* to implement lodash's _.debounce and _.throttle functions. Though the actual functions | |
* in both underscore and lodash took days to define, and refine, and the developers | |
* who implemented them were probably not under a 40 minute time limit. | |
* | |
* I have struggled with this myself when I interviewed at a few places last year. My | |
* approach towards preparing for these questions was to dive into the source code of | |
* lodash and underscore and understand what the functions were doing. Unfortunately, | |
* the source code for these functions is pretty complex (and the variable names are hard for me to follow, | |
* they reference other functions, and they have a bunch of options all of which are not strictly | |
* necessary for the core functionality), and even after spending time understanding what the code is doing, | |
* I wasn't able to re-implement it in my interviews in 40 minutes, and I suspect | |
* it's probably the case for most interviewees. This is my attempt to provide everyone | |
* an extremely simple code for debounce - simple enough for the readers to understand, and | |
* implement themselves. | |
* | |
* Whether or not this is a good question to gauge if someone is a good FE engineer is a whole | |
* another question which I won't get into here. | |
* | |
* This is my attempt at deriving the implementations of both `debounce` and `throttle` functions from their | |
* text description so that I never have to think about it again. | |
*/ | |
/** | |
* Problem: Debouncing a function means, ensuring that a sequence of calls to that function within a small amount of time, | |
* only lead to the function execution 1 time. Debouncing is the process of ensuring a series of consecutive function | |
* calls, lead only to an actual, single function invokation. Given this problem description, let's derive the implementation | |
* of the `debounce` function. | |
*/ | |
// takes as it's argument the function that needs to be debounced, like a scroll handler. | |
// this function should return a function (let's call it A) , which will only call the original | |
// `functionThatNeedsToBeDebounced` once, no matter how many times A is called by callers within the debounce interval. | |
const INTERVAL = 5000; | |
function debounce(functionThatNeedsToBeDebounced) { | |
let timerId; | |
return function() { | |
if (timerId !== undefined) { | |
// this means this function was invoked before and | |
// we're still waiting for the original interval to get over. | |
clearTimeout(timerId); | |
} | |
timerId = setTimeout(() => { | |
timerId = undefined; | |
functionThatNeedsToBeDebounced.apply(this, arguments); | |
}, INTERVAL); | |
} | |
} | |
// Now lets test this here: | |
// helper function to aid us in testing | |
function now() { | |
return new Date().getTime(); | |
}; | |
const debouncedConsoleLog = debounce(console.log.bind(console)); | |
for(let i = 0; i < 5; i++) { | |
console.log("Time before calling is: " , now()); | |
debouncedConsoleLog("Hello, world"); | |
} | |
// let's call it less frequently here. | |
setTimeout(() => { | |
console.log("Time before calling the second time is: " , now()); | |
debouncedConsoleLog("Hello, world2"); | |
}, 6000); | |
/** | |
* You can run the above function in jsfiddle and it works as expected. Of course, | |
* it doesn't take any options such as "WAIT" or "immediate" which modifies the debounce behavior, but | |
* those would be trivial to add to the above code. | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment