最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Javascript: How do I tweak my debounce function to take an IF conditional? - Stack Overflow

programmeradmin2浏览0评论

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!!');
}

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!!');
}
Share Improve this question edited Jun 29, 2012 at 23:55 mOrloff asked Jun 29, 2012 at 23:46 mOrloffmOrloff 2,6276 gold badges33 silver badges48 bronze badges 6
  • So what does this do exactly? I know denouncing in electronics but can't seem to figure out how that applies here. – sachleen Commented Jun 29, 2012 at 23:58
  • You could move the if (toggle) { check inside the foo function... That of course, would violate DRY in case you have multiple functions. – Šime Vidas Commented Jun 29, 2012 at 23:59
  • @arttronics From what I understand, OP wants to debounce (e.g. delay) the if-check. He doesn't want to test toggle immediately, but later, at the moment the function actually is invoked. – Šime Vidas Commented Jun 30, 2012 at 0:02
  • @Šime Vidas : Yeah, I'm trying to get my code as DRY (do-not repeat yourself) as possible, which is why I'm hoping to keep the debounce as a standalone of some sort. – mOrloff Commented Jun 30, 2012 at 0:05
  • @sachleen the real-life implementation is on an input field on a Settings UI. The inputs have a top and bottom limit (dynamically generated based on environment). If we need to enforce the limits, that naturally has to wait until the user is (or should be) done entering their value. HTH. – mOrloff Commented Jun 30, 2012 at 0:23
 |  Show 1 more ment

1 Answer 1

Reset to default 8

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 remend 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.

发布评论

评论列表(0)

  1. 暂无评论