dojo.Deferred errbacks
What happens when an error sneaks into a sequence of chained then()'s?
by parente
HTML
<input type="checkbox" id="first" checked /> First step succeeds?<br/>
<input type="checkbox" id="second" checked /> Second step succeeds?<br/>
<input type="checkbox" id="third" checked /> Third step succeeds?<br/>
<button onclick="run_errback_on_every_step();">Run with error handler throwing on each step</button><br />
<button onclick="run_errback_on_last_step();">Run with error handler on last step only</button>
<div id="log"></div>
CSS
.callback {
color: green;
}
.errback {
color: red;
}
JavaScript
var steps;
function start() {
var def = new dojo.Deferred();
setTimeout(dojo.partial(_timeout, def), 0);
return def;
}
function _timeout(def) {
var next = new dojo.Deferred();
var id = steps.shift();
if (id === undefined) {
return;
}
_log(id + ' timer fired', 'timer');
if (dojo.attr(id, 'checked')) {
_log('invoking ' + id + ' callback', 'timer');
def.callback(next);
setTimeout(dojo.partial(_timeout, next), 0);
} else {
_log('invoking ' + id + ' errback', 'timer');
def.errback(new Error('failed ' + id));
}
}
function _log(text, cls) {
dojo.create('p', {
innerHTML: text,
className: cls
}, dojo.byId('log'));
}
function run_errback_on_every_step() {
steps = ['first', 'second', 'third'];
dojo.empty('log');
start().then(function(next) {
_log('first callback', 'callback');
return next;
}, function(err) {
_log('first errback', 'errback');
throw err;
}).then(function(next) {
_log('second callback', 'callback');
return next;
}, function(err) {
_log('second errback', 'errback');
throw err;
}).then(function(next) {
_log('third callback', 'callback');
return next;
}, function(err) {
_log('third errback', 'errback');
throw err;
});
}
function run_errback_on_last_step() {
steps = ['first', 'second', 'third'];
dojo.empty('log');
start().then(function(next) {
_log('first callback', 'callback');
return next;
}).then(function(next) {
_log('second callback', 'callback');
return next;
}).then(function(next) {
_log('third callback', 'callback');
return next;
}, function(err) {
_log('only errback', 'errback');
});
}