Skip to content

Commit 52c41e6

Browse files
committed
Fix order of flushed debouncers to match 1.x
1 parent 7485a60 commit 52c41e6

File tree

2 files changed

+35
-43
lines changed

2 files changed

+35
-43
lines changed

lib/utils/debounce.html

+13-7
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,19 @@
5050
*/
5151
cancel() {
5252
if (this.isActive()) {
53-
this._asyncModule.cancel(this._timer);
53+
this._cancelAsync();
5454
this._timer = null;
55+
debouncerQueue.delete(this);
5556
}
5657
}
58+
/**
59+
* Cancels a debouncer's async callback.
60+
*
61+
* @return {void}
62+
*/
63+
_cancelAsync() {
64+
this._asyncModule.cancel(/** @type {number} */(this._timer));
65+
}
5766
/**
5867
* Flushes an active debouncer and returns a reference to itself.
5968
*
@@ -105,7 +114,9 @@
105114
*/
106115
static debounce(debouncer, asyncModule, callback) {
107116
if (debouncer instanceof Debouncer) {
108-
debouncer.cancel();
117+
// Cancel the async callback, but leave in debouncerQueue if it was
118+
// enqueued, to maintain 1.x flush order
119+
debouncer._cancelAsync();
109120
} else {
110121
debouncer = new Debouncer();
111122
}
@@ -127,11 +138,6 @@
127138
* @return {void}
128139
*/
129140
Polymer.enqueueDebouncer = function(debouncer) {
130-
// Re-enqueued debouncers are put at the end of the queue; for Set, this
131-
// means removing and re-adding, since forEach traverses insertion order
132-
if (debouncerQueue.has(debouncer)) {
133-
debouncerQueue.delete(debouncer);
134-
}
135141
debouncerQueue.add(debouncer);
136142
};
137143

test/unit/debounce.html

+22-36
Original file line numberDiff line numberDiff line change
@@ -211,47 +211,33 @@
211211
});
212212

213213
suite('enqueueDebouncer & flush', function() {
214-
function testEnqueue(shouldFlush, done) {
215-
// Longer-running debouncer
216-
const timeoutCallback = sinon.spy(() => actualCallbacks.push(timeoutCallback));
217-
Polymer.enqueueDebouncer(Polymer.Debouncer.debounce(null, Polymer.Async.timeOut, timeoutCallback));
218-
// Set of short-running debouncers enqueued in the middle of first set
219-
const nestedCallbacks = [];
220-
for (let i=0; i<150; i++) {
221-
nestedCallbacks.push(sinon.spy(() =>
222-
actualCallbacks.push(nestedCallbacks[i])));
223-
}
224-
// First set of short-running debouncers
225-
const microtaskCallbacks = [];
226-
for (let i=0; i<150; i++) {
227-
microtaskCallbacks.push(sinon.spy(() => {
228-
actualCallbacks.push(microtaskCallbacks[i]);
229-
if (i === 125) {
230-
nestedCallbacks.forEach(cb =>
231-
Polymer.enqueueDebouncer(Polymer.Debouncer.debounce(null, Polymer.Async.microTask, cb)));
232-
}
233-
}));
234-
}
235-
microtaskCallbacks.forEach(cb =>
236-
Polymer.enqueueDebouncer(Polymer.Debouncer.debounce(null, Polymer.Async.microTask, cb)));
237-
// Expect short before long
238-
let expectedCallbacks;
239-
const actualCallbacks = [];
240-
const verify = () => {
241-
actualCallbacks.forEach(cb => assert.isTrue(cb.calledOnce));
242-
assert.deepEqual(expectedCallbacks, actualCallbacks);
243-
done();
214+
215+
const testEnqueue = (shouldFlush, done) => {
216+
const actualOrder = [];
217+
let i=1;
218+
const enqueue = (type, {db, cb} = {}) => {
219+
cb = cb || (() => actualOrder.push(cb));
220+
db = Polymer.Debouncer.debounce(db, type, cb);
221+
Polymer.enqueueDebouncer(db);
222+
return {db, cb};
244223
};
224+
const db1 = enqueue(Polymer.Async.microTask);
225+
const db2 = enqueue(Polymer.Async.microTask);
226+
const db3 = enqueue(Polymer.Async.timeOut);
227+
const db4 = enqueue(Polymer.Async.microTask);
228+
enqueue(Polymer.Async.microTask, db2);
229+
enqueue(Polymer.Async.microTask, db1);
245230
if (shouldFlush) {
246-
expectedCallbacks = [timeoutCallback, ...microtaskCallbacks, ...nestedCallbacks];
247231
Polymer.flush();
248-
// When flushing, order is order of enqueing
249-
verify();
232+
assert.deepEqual(actualOrder, [db1.cb, db2.cb, db3.cb, db4.cb]);
233+
done();
250234
} else {
251-
expectedCallbacks = [...microtaskCallbacks, ...nestedCallbacks, timeoutCallback];
252-
Polymer.Async.timeOut.run(verify);
235+
Polymer.Async.timeOut.run(() => {
236+
assert.deepEqual(actualOrder, [db4.cb, db2.cb, db1.cb, db3.cb]);
237+
done();
238+
});
253239
}
254-
}
240+
};
255241

256242
test('non-flushed', function(done) {
257243
testEnqueue(false, done);

0 commit comments

Comments
 (0)