From e24d595a306c4e63d189954c917360946a1de392 Mon Sep 17 00:00:00 2001 From: Blake Simpson Date: Thu, 13 Feb 2014 15:36:07 +0100 Subject: [PATCH 1/2] Allow _.throttle to function correctly after the system time is updated --- test/functions.js | 20 ++++++++++++++++++++ underscore.js | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/test/functions.js b/test/functions.js index 14ea934c2..474f615c1 100644 --- a/test/functions.js +++ b/test/functions.js @@ -278,6 +278,26 @@ }, 96); }); + asyncTest('throttle continues to function after system time is set backwards', 2, function() { + var counter = 0; + var incr = function(){ counter++; }; + var throttledIncr = _.throttle(incr, 100); + var origNowFunc = _.now; + + throttledIncr(); + ok(counter == 1); + _.now = function () { + return new Date(2013, 0, 1, 1, 1, 1); + }; + + _.delay(function() { + throttledIncr(); + ok(counter == 2); + start(); + _.now = origNowFunc; + }, 200); + }); + asyncTest('debounce', 1, function() { var counter = 0; var incr = function(){ counter++; }; diff --git a/underscore.js b/underscore.js index ca61fdc3a..cb9318910 100644 --- a/underscore.js +++ b/underscore.js @@ -695,7 +695,7 @@ var remaining = wait - (now - previous); context = this; args = arguments; - if (remaining <= 0) { + if (remaining <= 0 || remaining > wait) { clearTimeout(timeout); timeout = null; previous = now; From fa3526055bf662a7f0940a2d930e8021a7abeb1e Mon Sep 17 00:00:00 2001 From: Blake Simpson Date: Fri, 14 Feb 2014 19:12:09 +0100 Subject: [PATCH 2/2] Add sanity check to _.debounce incase system time is moved between calls --- test/functions.js | 22 ++++++++++++++++++++++ underscore.js | 3 ++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/test/functions.js b/test/functions.js index 474f615c1..a89cc6a73 100644 --- a/test/functions.js +++ b/test/functions.js @@ -334,6 +334,28 @@ _.delay(function(){ equal(counter, 1, 'incr was debounced'); start(); }, 96); }); + asyncTest('debounce after system time is set backwards', 2, function() { + var counter = 0; + var origNowFunc = _.now; + var debouncedIncr = _.debounce(function(){ + counter++; + }, 100, true); + + debouncedIncr(); + equal(counter, 1, 'incr was called immediately'); + + _.now = function () { + return new Date(2013, 0, 1, 1, 1, 1); + }; + + _.delay(function() { + debouncedIncr(); + equal(counter, 2, 'incr was debounced successfully'); + start(); + _.now = origNowFunc; + },200); + }); + test('once', function() { var num = 0; var increment = _.once(function(){ num++; }); diff --git a/underscore.js b/underscore.js index cb9318910..702cb5259 100644 --- a/underscore.js +++ b/underscore.js @@ -717,7 +717,8 @@ var later = function() { var last = _.now() - timestamp; - if (last < wait) { + + if (last < wait && last > 0) { timeout = setTimeout(later, wait - last); } else { timeout = null;