Skip to content

Commit

Permalink
Merge pull request #1949 from Polymer/1933-1759-kschaaf
Browse files Browse the repository at this point in the history
Catch errors in async queue & re-start. Fixes #1933. Fixes #1759.
  • Loading branch information
Steve Orvell committed Jun 24, 2015
2 parents f62a80d + d07e5cf commit 80533c2
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 35 deletions.
70 changes: 36 additions & 34 deletions src/lib/async.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,60 +9,62 @@
-->
<script>

Polymer.Async = (function() {

var currVal = 0;
var lastVal = 0;
var callbacks = [];
var twiddle = document.createTextNode('');
Polymer.Async = {

function runAsync(callback, waitTime) {
_currVal: 0,
_lastVal: 0,
_callbacks: [],
_twiddleContent: 0,
_twiddle: document.createTextNode(''),

run: function (callback, waitTime) {
if (waitTime > 0) {
return ~setTimeout(callback, waitTime);
} else {
twiddle.textContent = currVal++;
callbacks.push(callback);
return currVal - 1;
this._twiddle.textContent = this._twiddleContent++;
this._callbacks.push(callback);
return this._currVal++;
}
}
},

function cancelAsync(handle) {
cancel: function(handle) {
if (handle < 0) {
clearTimeout(~handle);
} else {
var idx = handle - lastVal;
var idx = handle - this._lastVal;
if (idx >= 0) {
if (!callbacks[idx]) {
if (!this._callbacks[idx]) {
throw 'invalid async handle: ' + handle;
}
callbacks[idx] = null;
this._callbacks[idx] = null;
}
}
}
},

function atEndOfMicrotask() {
var len = callbacks.length;
_atEndOfMicrotask: function() {
var len = this._callbacks.length;
for (var i=0; i<len; i++) {
var cb = callbacks[i];
var cb = this._callbacks[i];
if (cb) {
cb();
try {
cb();
} catch(e) {
// Clear queue up to this point & start over after throwing
i++;
this._callbacks.splice(0, i);
this._lastVal += i;
this._twiddle.textContent = this._twiddleContent++;
throw e;
}
}
}
callbacks.splice(0, len);
lastVal += len;
this._callbacks.splice(0, len);
this._lastVal += len;
}
};

new (window.MutationObserver || JsMutationObserver)(atEndOfMicrotask)
.observe(twiddle, {characterData: true})
;

// exports

return {
run: runAsync,
cancel: cancelAsync
};

})();
new (window.MutationObserver || JsMutationObserver)
(Polymer.Async._atEndOfMicrotask.bind(Polymer.Async))
.observe(Polymer.Async._twiddle, {characterData: true});

</script>
64 changes: 63 additions & 1 deletion test/unit/async.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<body>

<script>

setup(function() {
window.Async = Polymer.Async;
});
Expand Down Expand Up @@ -80,6 +80,68 @@
});
});

test('error handling', function(done) {
var called1 = 0;
var called2 = 0;
var called3 = 0;
var called4 = 0;
var called5 = 0;
var callback1 = function() {
called1++;
};
var callback2 = function() {
called2++;
throw new Error('intentional error 1');
};
var callback3 = function() {
called3++;
Async.run(callback5);
throw new Error('intentional error 2');
};
var callback4 = function() {
called4++;
};
var callback5 = function() {
called5++;
};
Async.run(callback1);
Async.run(callback2);
Async.run(callback3);
Async.run(callback4);
// Force synchronous microtask, since we can't catch the error otherwise
assert.throws(function() {
Async._atEndOfMicrotask();
});
// Have been called
assert.equal(called1, 1);
assert.equal(called2, 1);
// Not yet called, due to exception
assert.equal(called3, 0);
assert.equal(called4, 0);
assert.equal(called5, 0);
// Force next synchronous microtask
assert.throws(function() {
Async._atEndOfMicrotask();
});
// Have been called
assert.equal(called1, 1);
assert.equal(called2, 1);
assert.equal(called3, 1);
// Not yet called, due to exception
assert.equal(called4, 0);
assert.equal(called5, 0);
// Wait for actual microtask, and verify remaining queue was flushed
setTimeout(function() {
// Have been called
assert.equal(called1, 1);
assert.equal(called2, 1);
assert.equal(called3, 1);
assert.equal(called4, 1);
assert.equal(called5, 1);
done();
});
});

});

suite('cancel no-wait async', function() {
Expand Down

0 comments on commit 80533c2

Please sign in to comment.