diff --git a/test/functions.js b/test/functions.js index e6c402a18..ff95f4368 100644 --- a/test/functions.js +++ b/test/functions.js @@ -146,6 +146,20 @@ $(document).ready(function() { _.delay(function(){ ok(counter == 1, "incr was debounced"); start(); }, 220); }); + asyncTest("functions: debounce asap", 2, function() { + var counter = 0; + var incr = function(){ counter++; }; + var debouncedIncr = _.debounce(incr, 50, true); + debouncedIncr(); debouncedIncr(); debouncedIncr(); + equal(counter, 1, 'incr was called immediately'); + setTimeout(debouncedIncr, 30); + setTimeout(debouncedIncr, 60); + setTimeout(debouncedIncr, 90); + setTimeout(debouncedIncr, 120); + setTimeout(debouncedIncr, 150); + _.delay(function(){ equal(counter, 1, "incr was debounced"); start(); }, 220); + }); + test("functions: once", function() { var num = 0; var increment = _.once(function(){ num++; }); diff --git a/underscore.js b/underscore.js index c4e8c8a59..c75bf4f75 100644 --- a/underscore.js +++ b/underscore.js @@ -548,15 +548,17 @@ // Returns a function, that, as long as it continues to be invoked, will not // be triggered. The function will be called after it stops being called for - // N milliseconds. - _.debounce = function(func, wait) { + // N milliseconds. If `immediate` is passed, trigger the function on the + // leading edge, instead of the trailing. + _.debounce = function(func, wait, immediate) { var timeout; return function() { var context = this, args = arguments; var later = function() { timeout = null; - func.apply(context, args); + if (!immediate) func.apply(context, args); }; + if (immediate && !timeout) func.apply(context, args); clearTimeout(timeout); timeout = setTimeout(later, wait); };