'debounce with ignoring all calls except the last using lodash
If I have a function foo
. It receives many calls at a short period of time.
function foo(name) {
console.log(`Hi ${name}, it is now: `, new Date());
}
Delaying consecutive function invocations (debouncing ) is working fine using lodash .
const debouncedFoo = _.debounce(foo, 1000 );
However, my target is to NOT execute this whole fleet of invocations even the timeout (1000
) have elapsed, and consider only the last invocation to be executed .
In other words, if i called debouncedFoo
5 times within 900 ms (which is less than "wait param" 1000ms ), I want foo
to be executed only once which is the last (5ᵗʰ) call .
Reading lodash documentation , I understood that debounce
is overloaded by 3ʳᵈ argument which is options. I used them and the expected behavior does not happen:
// first attempt
const debouncedFoo = _.debounce(foo, 1000, {leading: true} );
// second attempt
const debouncedFoo = _.debounce(foo, 1000, {trailing: false} );
Solution 1:[1]
Not familiar with lodash, but you can implement that behavior easily:
function debounce(cb, duration) {
let timer;
return (...args) => {
clearTimeout(timer);
timer = setTimeout(() => {
cb(...args);
}, duration);
};
}
function debounce(cb, duration) {
var timer;
return function() {
var args = arguments;
clearTimeout(timer);
timer = setTimeout(function() {
cb.apply(null, args);
}, duration);
};
}
var call = debounce(console.log.bind(console), 1000);
setTimeout(function(){ call(200); }, 200);
setTimeout(function(){ call(400); }, 400);
setTimeout(function(){ call(600); }, 600);
setTimeout(function(){ call(800); }, 800);
setTimeout(function(){ call(900); }, 900);
Solution 2:[2]
Like @AndyO mentioned, make sure you're not re-creating the debounced function upon every state change.
I had the same problem, so I used useCallback
to solve it.
import React, { useCallback } from 'React';
import { debounce } from 'lodash';
const myFunction = () => { // some logic };
const debouncedMyFunction = useCallback(debounce(myFunction, 300), []);
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Abdennour TOUMI |
Solution 2 | Daniel Krichevsky |