Flame_Phoenix
Flame_Phoenix

Reputation: 17574

How to use _.debounce correctly?

Background

Imagine you have an app where you receive tons of info when you make a request. In my app about restaurants, I want to calculate the average price of all menus every time I get a request containing several restaurants:

var avg = menus => {
  const sum = menus.reduce( ( sum, currMenu ) => currMenu.price + sum , 0);
  console.log( sum / menus.length );
};

Our Solution

The problem is that I get so many restaurants my app starts to lag! Solution? Well, since the user doesn't care to see the updated average every 0.001 ms we decided to use debounce to show an updated average every 100ms or so:

var debounceAvg = _.debounce( avg, 100 );

For an article on how debounce works have a read at here:

Problem

So, now we have a debounce function. To test it I have a test function:

var myMenus = [ { price: 1 }, { price: 2 }, { price: 3 } ];

var timer = setInterval( params => {
    console.log("executing timer");
    debounceAvg(params);
}, 20, myMenus );

setTimeout( () => { clearInterval(timer) }, 5000);

This function should print to the log the avg price of all menus every 100ms even though it is being invoked every 20ms. However I only end up with 2 logs containing the avg price - the first and the last.

Question

What am I doing wrong ?

Upvotes: 3

Views: 1167

Answers (1)

Matt Spinks
Matt Spinks

Reputation: 6698

You are actually logging outside your debounce function. So your logging is happening every time through the loop. That's why you are getting all those zeros. You can either do your logging inside your debounce function (you could pass it in as a parameter), or check for a change in your loop.

Here is a possible implementation of passing your function in as a param for testing. I'm not sure that I fully understand your logic in the functions, but this should at least get you started:

var val = 0;
avg = function(menus, callback) {
  val = menus.reduce( ( sum, currMenu) => currMenu.price + sum , 0)) / menus.length;
  callback();
  return val;
}
var testDebounce = iterations => {
    const myMenus = [];
    for( let i = 0; i < iterations; i++ ) {
        myMenus.push( { price: i } );
        debounceAvg(aparts, function() {
          console.log(val);
        });
    }
};

Upvotes: 2

Related Questions