Ensure _.debounce performs a trailing call, when both leading and trailing are true, only after the throttled function is called more than once. [closes #243]

Former-commit-id: 59ac6bc4ece373623f2bd753b662b8cc974cabc8
This commit is contained in:
John-David Dalton
2013-04-17 08:43:18 -07:00
parent 3b2e0e34ef
commit e7c44274b0
2 changed files with 23 additions and 10 deletions

View File

@@ -4478,13 +4478,14 @@
*/ */
function debounce(func, wait, options) { function debounce(func, wait, options) {
var args, var args,
inited,
result, result,
thisArg, thisArg,
timeoutId, timeoutId,
trailing = true; trailing = true;
function delayed() { function delayed() {
timeoutId = null; inited = timeoutId = null;
if (trailing) { if (trailing) {
result = func.apply(thisArg, args); result = func.apply(thisArg, args);
} }
@@ -4497,15 +4498,15 @@
trailing = 'trailing' in options ? options.trailing : trailing; trailing = 'trailing' in options ? options.trailing : trailing;
} }
return function() { return function() {
var isLeading = leading && !timeoutId;
args = arguments; args = arguments;
thisArg = this; thisArg = this;
clearTimeout(timeoutId); clearTimeout(timeoutId);
timeoutId = setTimeout(delayed, wait);
if (isLeading) { if (!inited && leading) {
inited = true;
result = func.apply(thisArg, args); result = func.apply(thisArg, args);
} else {
timeoutId = setTimeout(delayed, wait);
} }
return result; return result;
}; };
@@ -4706,10 +4707,9 @@
trailing = true; trailing = true;
function trailingCall() { function trailingCall() {
lastCalled = new Date;
timeoutId = null; timeoutId = null;
if (trailing) { if (trailing) {
lastCalled = new Date;
result = func.apply(thisArg, args); result = func.apply(thisArg, args);
} }
} }

View File

@@ -552,16 +552,29 @@
}, 64); }, 64);
}); });
test('should work with `leading` option', function() { asyncTest('should work with `leading` option', function() {
_.each([true, { 'leading': true }], function(options) { var counts = [0, 0, 0];
var withLeading = _.debounce(_.identity, 32, options); _.each([true, { 'leading': true }], function(options, index) {
var withLeading = _.debounce(function(value) {
counts[index]++;
return value;
}, 32, options);
equal(withLeading('x'), 'x'); equal(withLeading('x'), 'x');
}); });
_.times(2, _.debounce(function() { counts[2]++; }, 32, { 'leading': true }));
strictEqual(counts[2], 1);
_.each([false, { 'leading': false }], function(options) { _.each([false, { 'leading': false }], function(options) {
var withoutLeading = _.debounce(_.identity, 32, options); var withoutLeading = _.debounce(_.identity, 32, options);
strictEqual(withoutLeading('x'), undefined); strictEqual(withoutLeading('x'), undefined);
}); });
setTimeout(function() {
deepEqual(counts, [1, 1, 2]);
QUnit.start();
}, 64);
}); });
asyncTest('should work with `trailing` option', function() { asyncTest('should work with `trailing` option', function() {