Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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} );
like image 975
Abdennour TOUMI Avatar asked Nov 10 '17 02:11

Abdennour TOUMI


People also ask

Should I use throttle or debounce?

It's simple. They do the exact same thing (rate limiting) except while throttle is being called it'll fire your function periodically, while debounce only fires once at the end. Example: If you're scrolling, throttle will slowly call your function while you scroll (every X milliseconds).

How does debounce Lodash work?

The Lodash debounce function returns a debounced function that when called will execute a function after X milliseconds pass since its last execution.

How do I cancel Lodash Debounce?

The easiest way to allow to cancel an already called function within its debounce period is to call it from a cancelable wrap. Really just add 3 lines of code and an optional condition. You cancel it by calling it again with abort = true .

What is debounce and how could you implement debounce?

The debounce() function forces a function to wait a certain amount of time before running again. The function is built to limit the number of times a function is called. The Send Request() function is debounced. Requests are sent only after fixed time intervals regardless of how many times the user presses the button.


2 Answers

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);
like image 169
Derek 朕會功夫 Avatar answered Oct 09 '22 06:10

Derek 朕會功夫


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), []);
like image 26
Daniel Krichevsky Avatar answered Oct 09 '22 06:10

Daniel Krichevsky