Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lodash _.debounce with separate queues for unique argument variants

I really appreciate lodash for its debounce and throttle functionality. I believe I understand the uses cases well and have implemented them dozens of times.

However, depending on requirements, there can be a significant and hard to catch error with _.debounce functions having arguments. That is the following:

Assume you have a debounce function called debounceFn that accepts one argument and has a debounce interval of 1000ms.

  • 100ms: debounceFn(1)
  • 200ms: debounceFn(2)
  • 300ms: debounceFn(2)
  • 400ms: debounceFn(1)
  • 500ms: debounceFn(1)

The child function will eventually call with an argument of 1. This works great for resize events where you only care about the last value, but what if you need separate debounced queues depending on arguments? That is, instead of the process called with an argument of 1, have the process called with argument 1 and with argument 2, but only called once (because they are both debounced).

As an extended and slightly more complex example, consider a combination of arguments below, where the combination produces a unique queue.

actual output:

  • a: lime b: kiwi

desired output (order of first two outputs could be flipped)

  • a: apple b: banana
  • a: apple b: orange
  • a: lime b: kiwi

var process = function(a, b) {
  document.writeln('a: ' + a + ' b: ' + b);
};

var debounceProcess = _.debounce(function(a, b) {
  process(a, b);
}, 1000);


setTimeout(function() {
  debounceProcess('apple', 'orange');
}, 100);
setTimeout(function() {
  debounceProcess('apple', 'banana');
}, 200);
setTimeout(function() {
  debounceProcess('apple', 'orange');
}, 300);
setTimeout(function() {
  debounceProcess('lime', 'kiwi');
}, 400);
<script src="https://cdn.rawgit.com/lodash/lodash/4.6.1/dist/lodash.min.js"></script>

I have seen many SO questions on _.debounce accepting an argument. That is no longer an interesting question, so - how do you create separate debounce queues?

What is an elegant way (simple, easy to read code) to accomplish this using the Lodash _.debounce function, Lodash library and JavaScript native capability? Perhaps a combination of _.debounce and _.memoize (I have tried wrapping _.debounce with _.memoize but will need to explore to understand memoize further). Or perhaps a function to 'hash' the arguments and create a new _.debounce queue for each combination of arguments?

like image 480
ryanm Avatar asked Apr 21 '16 17:04

ryanm


Video Answer


1 Answers

Store the different debounced functions in an object, where the key represents the arguments. This works well in your use-case, because the arguments are strings.

var process = function(a, b) {
  $('body').append($('<p>').text('a: ' + a + ' b: ' + b));
};

function debounceProcess(a, b) {
  if (! debounceProcess.queues)    { debounceProcess.queues = {}; }
  if (! debounceProcess.queues[a]) { debounceProcess.queues[a] = {}; }
  if (! debounceProcess.queues[a][b]) {
    debounceProcess.queues[a][b] = _.debounce(function(a, b) {
      process(a, b);
    }, 1000);
  }
  return debounceProcess.queues[a][b](a, b);
};

setTimeout(function() {
  debounceProcess('apple', 'orange');
}, 100);
setTimeout(function() {
  debounceProcess('apple', 'banana');
}, 200);
setTimeout(function() {
  debounceProcess('apple', 'orange');
}, 300);
setTimeout(function() {
  debounceProcess('lime', 'kiwi');
}, 400);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.rawgit.com/lodash/lodash/4.6.1/dist/lodash.min.js"></script>
like image 73
Flimm Avatar answered Nov 07 '22 10:11

Flimm