Reputation: 2617
I found a bug, and tracked it down.
You can see a simplified example of my code here.
As it turns out, I need to debounce my if()
statement rather than debouncing the function itself.
I'd like to keep the debounce as a standalone function, but I'm not sure then how to pass the conditional in.
Any pointers?
Here's the code:
var foo = function(xyz) {
alert(xyz);
};
function setter(func, arg1, arg2) {
return {
fn: func,
arg1: arg1,
arg2: arg2
};
}
function debounce(someObject) {
var duration = someObject.arg2 || 100;
var timer;
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(function() {
someObject.fn(someObject.arg1);
timer = 0;
}, duration);
}
var toggle = true;
if (toggle) {
debounce(setter(foo, 'The best things in life are worth waiting for.', 1250));
} else {
foo('Instant gratification is sweet!!');
}
Upvotes: 2
Views: 3587
Reputation: 7181
Using your example, why not pass toggle in as arg 1... something like:
var toggle = true;
var debouncedFunk = function(toggle) {
if (toggle)
// the function call
else
// something else
};
debounce(debouncedFunk, toggle, 1250);
You should also look into using the Function objects .call
and .apply
methods. They are for calling the function and passing in arguments. Taking the example function:
var example = function(one, two) {
// Logic here
};
You can call it in three ways:
// First
example(1, 2);
// Second
example.call({}, 1, 2);
// Third
example.apply({}, [ 1, 2 ]);
The first is the standard way to call a function. The difference between the first and the .call
is that the first parameter to .call
is the context object of the function (what this
will point to inside the function), the other parameters are passed after that (and a known list is required for .call
. The benefit of .apply
is that you can pass an array to the function of arguments and they will be assigned to the parameter list appropriately, the first parameter is still the context object.
It would simplify your debounce function, instead of having to deal with a structured object as you currently do.
A suggestion for your debounce:
var debounce = function(funk, delay) {
var args = [];
if (arguments.length > 2)
args = [].slice.call(arguments, 2);
setTimeout(function() { funk.apply({}, args); }, delay);
};
Changing your current if to:
var toggle = true;
var debouncedFunk = function(toggle) {
if (toggle)
// Do if true
else
// DO if false
};
debounce(debouncedFunk, 1000, toggle);
Maybe too much information (sorry)?
As a last note, I'd recommend using a framework (if possible) where these functions have been implemented already (and many other useful functions) such as Underscore. Using Underscore your example would look like:
// Define debouncedFunk and toggle
debouncedFunk = _.bind(debouncedFunk, {}, toggle);
debouncedFunk = _.debounce(debouncedFunk, 1000);
debouncedFunk();
EDIT
Fixed the underscore example, _.debounce
returns a function that will execute only after the delay but it still needs to be called.
Upvotes: 8