Lodash Debounce not debouncing
Asked Answered
A

2

28

I'm trying to debounce a function using Lodash, and while it's invoking the function, it doesn't seem to debounce it at all. My issue doesn't seem to be the same mistake as what I've seen elsewhere on SO or Google (generally, that they're not invoking the function that _.debounce returns).

My currently super-simple implementation is as follows (in Angular with CoffeeScript):

  s.search = -> _.debounce( s._makeSearchRequest, 1000 )()

  s._makeSearchRequest = -> console.log("making search request")

In JS, I believe that's:

  s.search = function() { _.debounce( s._makeSearchRequest, 1000 )() }

  s._makeSearchRequest = function() { console.log("making search request") }

I run s.search() by typing into an input box, and if I type gibberish very quickly, the console prints out "making search request" on every key press, so many times per second -- indicating that it hasn't been debounced at all.

Any ideas what's I'm doing wrong?

Avellaneda answered 18/3, 2015 at 19:58 Comment(1)
Possible duplicate of lodash debounce not working in anonymous functionAmbrotype
C
49

_.debounce creates a function that debounces the function that's passed into it. What your s.search function is doing is calling _.debounce all over again every time s.search is called. This creates a whole new function every time, so there's nothing to debounce.

So the solution is to remove the arrow and the extra pair of parentheses, and make sure that s._makeSearchRequest is defined before you access it:

s._makeSearchRequest = -> console.log("making search request")

s.search = _.debounce( s._makeSearchRequest, 1000 )

Example (using JavaScript):

var s;

s = {};

s._makeSearchRequest = function(q) {
  return console.log("making search request: " + q);
};

s.search = _.debounce(s._makeSearchRequest, 1000);

// call s.search three times in a row
s.search(1);
s.search(2);
s.search(3);

// call s.search after 500 ms
setTimeout(s.search, 500, 4);

// call s.search after 3 seconds
setTimeout(s.search, 3000, 5);

// timer to show passage of time
var i = 0;
var t = setInterval(function () {
    i += 1;
    console.log(i + " seconds elapsed");
    if (i > 5) { clearInterval(t); }
}, 1000);
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/3.5.0/lodash.min.js"></script>
Constantine answered 18/3, 2015 at 20:14 Comment(2)
I am confused here, I read that debounce ignores the calls made to it during the timer is running and when the timer expires it calls the function with the last function call arguments, is that right? if thats right then the above debounce is incorrect, it is invoking all the function calls. @Constantine could you please help with this?Hyrcania
@Hyrcania It's not invoking all of the function calls. If you look at the code and the log output, s.search is called five times in the code, but only executes two times. I've just added a parameter to makeSearchRequest to demonstrate this more clearly.Constantine
T
3

Try this:

s._makeSearchRequest = function() {
    console.log("making search request");
}

s.search = _.debounce( s._makeSearchRequest, 1000 );

POC: http://jsfiddle.net/bvaughn/3saj6znk/

Toms answered 18/3, 2015 at 20:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.