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'); }); }
<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>
.callback { color: green; } .errback { color: red; }