'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