Created
February 9, 2013 04:25
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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