Skip to content

Commit

Permalink
Fix order of flushed debouncers to match 1.x
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinpschaaf committed Feb 28, 2019
1 parent 567c10b commit b9d4959
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 44 deletions.
21 changes: 14 additions & 7 deletions lib/utils/debounce.js
Expand Up @@ -45,11 +45,19 @@ export class Debouncer {
*/
cancel() {
if (this.isActive()) {
this._asyncModule.cancel(/** @type {number} */(this._timer));
this._cancelAsync();
this._timer = null;
debouncerQueue.delete(this);
}
}
/**
* Cancels a debouncer's async callback.
*
* @return {void}
*/
_cancelAsync() {
this._asyncModule.cancel(/** @type {number} */(this._timer));
}
/**
* Flushes an active debouncer and returns a reference to itself.
*
Expand Down Expand Up @@ -105,7 +113,9 @@ export class Debouncer {
*/
static debounce(debouncer, asyncModule, callback) {
if (debouncer instanceof Debouncer) {
debouncer.cancel();
// Cancel the async callback, but leave in debouncerQueue if it was
// enqueued, to maintain 1.x flush order
debouncer._cancelAsync();
} else {
debouncer = new Debouncer();
}
Expand All @@ -123,14 +133,11 @@ let debouncerQueue = new Set();
* @return {void}
*/
export const enqueueDebouncer = function(debouncer) {
// Re-enqueued debouncers are put at the end of the queue; for Set, this
// means removing and re-adding, since forEach traverses insertion order
if (debouncerQueue.has(debouncer)) {
debouncerQueue.delete(debouncer);
}
debouncerQueue.add(debouncer);
};

window.debouncerQueue = debouncerQueue;

/**
* Flushes any enqueued debouncers
*
Expand Down
66 changes: 29 additions & 37 deletions test/unit/debounce.html
Expand Up @@ -212,56 +212,48 @@
});

suite('enqueueDebouncer & flush', function() {
function testEnqueue(shouldFlush, done) {
// Longer-running debouncer
const timeoutCallback = sinon.spy(() => actualCallbacks.push(timeoutCallback));
enqueueDebouncer(Debouncer.debounce(null, timeOut, timeoutCallback));
// Set of short-running debouncers enqueued in the middle of first set
const nestedCallbacks = [];
for (let i=0; i<150; i++) {
nestedCallbacks.push(sinon.spy(() =>
actualCallbacks.push(nestedCallbacks[i])));
}
// First set of short-running debouncers
const microtaskCallbacks = [];
for (let i=0; i<150; i++) {
microtaskCallbacks.push(sinon.spy(() => {
actualCallbacks.push(microtaskCallbacks[i]);
if (i === 125) {
nestedCallbacks.forEach(cb =>
enqueueDebouncer(Debouncer.debounce(null, microTask, cb)));
}
}));
}
microtaskCallbacks.forEach(cb =>
enqueueDebouncer(Debouncer.debounce(null, microTask, cb)));
// Expect short before long
let expectedCallbacks;
const actualCallbacks = [];
const verify = () => {
actualCallbacks.forEach(cb => assert.isTrue(cb.calledOnce));
assert.deepEqual(expectedCallbacks, actualCallbacks);
done();

const testEnqueue = (shouldFlush, done) => {
const actualOrder = [];
let i=1;
const enqueue = (type, {db, cb} = {}) => {
// cb = cb || (() => actualOrder.push(cb));
if (!cb) {
cb = (() => actualOrder.push(cb));
Object.defineProperty(cb, 'name', {value: `db${i}`}); i++;
}
db = Debouncer.debounce(db, type, cb);
enqueueDebouncer(db);
return {db, cb};
};
const db1 = enqueue(microTask);
const db2 = enqueue(microTask);
const db3 = enqueue(timeOut);
const db4 = enqueue(microTask);
enqueue(microTask, db2);
enqueue(microTask, db1);
if (shouldFlush) {
expectedCallbacks = [timeoutCallback, ...microtaskCallbacks, ...nestedCallbacks];
flush();
// When flushing, order is order of enqueing
verify();
assert.deepEqual(actualOrder, [db1.cb, db2.cb, db3.cb, db4.cb]);
done();
} else {
expectedCallbacks = [...microtaskCallbacks, ...nestedCallbacks, timeoutCallback];
timeOut.run(verify);
timeOut.run(() => {
assert.deepEqual(actualOrder, [db4.cb, db2.cb, db1.cb, db3.cb]);
done();
});
}
}
};

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

test('flushed', function(done) {
test.only('flushed', function(done) {
testEnqueue(true, done);
});

test('re-enqueued ')

});
});
</script>
Expand Down

0 comments on commit b9d4959

Please sign in to comment.