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.
debounceFn(1)
debounceFn(2)
debounceFn(2)
debounceFn(1)
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?
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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With