The task is to implement an enhanced debounce which has an option to invoke right away or after a delay.
The boilerplate code
function debounce(func, wait, option = {leading: false, trailing: true}) {
// your code here
}
Keep track of the delay required and the latest call data
let timer = null;
let lastArgs;
let lastThis;
When the function is called, clear any existing timer and start a new one
return function(...args) {
lastArgs = args;
lastThis = this;
if(timer) clearTimeout(timer);
If there is no active timer, the function executes immediately on first call.
const shouldCallNow = option.leading && !timer
if(shouldCallNow) {
func.apply(lastThis, lastArgs)
lastArgs = lastThis = null;
}
If there is a timer, the function executes after a waiting period expires
timer = setTimeout(() => {
timer = null;
if(option.trailing && lastArgs) {
func.apply(lastThis, lastArgs)
lastArgs = lastThis = null;
}
}, wait)
The final code
function debounce(func, wait, option = {leading: false, trailing: true}) {
// your code here
let timer = null;
let lastArgs;
let lastThis;
return function(...args) {
lastArgs = args;
lastThis = this;
const shouldCallNow = option.leading && !timer;
if(timer) clearTimeout(timer);
timer = setTimeout(() => {
timer = null;
if(option.trailing && lastArgs) {
func.apply(lastThis, lastArgs)
lastArgs = lastThis = null;
}
}, wait)
if(shouldCallNow) {
func.apply(lastThis, lastArgs);
lastArgs = lastThis = null;
}
}
}
That's all folks!
Top comments (0)