Skip to content

Instantly share code, notes, and snippets.

@aramk
Created February 9, 2013 04:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aramk/4743836 to your computer and use it in GitHub Desktop.
Save aramk/4743836 to your computer and use it in GitHub Desktop.
Resolves each dojo.Deferred in the queue sequentially, waiting for the previous to complete before moving on. Use this with DeferredWrapper: https://gist.github.com/aramkocharyan/4743839
define([
'dojo/_base/declare',
'dojo/_base/lang',
'dojo/Deferred',
'utility/Log'
], function (declare, lang, Deferred, Log) {
// Internal ID for more useful logs
var queueID = 0;
return declare([Deferred], {
// summary:
// Resolves each Deferred in the queue sequentially, waiting for the previous to complete before moving on.
// description:
// The queue should be passed an array of DeferredWrapper objects to allow deferring any asynchronous code until
// the previous ones in the list have completed. Providing a Deferred object will resolve it immediately and make this class useless.
// TODO inheritance doesn't override Deferred functions since it's not a declared "class" - it's a plain function
id: null,
queue: null,
ignition: null,
results: [],
constructor: function (queue) {
this.id = queueID++;
this.queue = queue;
if (queue.length > 0) {
// This uses tail recursion. This is the "accumulator" - the last callback to run
var callback = lang.hitch(this, function (deferred, result) {
// TODO allow handling of errors
Log.info(this._name() + ' complete with results', this.results);
this.resolve(this.results);
});
// Start with the last item in the queue and wrap it around the callback for all queue items
for (var i = queue.length; i--;) {
var deferred = queue[i];
lang.hitch(this, function (deferred, oldCallback, i) {
// Wrap our callbacks so far in another callback
callback = lang.hitch(this, function (prevDeferred, prevResult) {
deferred.resolve();
var df = deferred.inner;
if (!deferred.inner) {
// This will execute immediately, not good
df = deferred;
Log.warn(this._name() + ' queue position ' + i + ' is not a DeferredWrapper');
}
return df.then(lang.hitch(this, function (result) {
Log.info(this._name() + ' called Deferred #' + i);
this.results.push(result);
// Recursion into earlier callbacks
oldCallback(deferred, result);
}));
});
})(deferred, callback, i);
}
this.ignition = new Deferred();
this.ignition.then(lang.hitch(this, function () {
callback(this.ignition);
}));
}
},
start: function () {
// summary:
// Starts executing the queue.
if (this.ignition) {
Log.info(this._name() + ' started');
this.ignition.resolve();
}
},
_name: function () {
return 'Deferred Queue #' + this.id;
}
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment