I need a loop that waits for an async call before continuing. Something like:
for ( /* ... */ ) {
someFunction(param1, praram2, function(result) {
//
A cleaner alternative to what @Ivo has suggested would be an Asynchronous Method Queue, assuming that you only need to make one async call for the collection.
(See this post by Dustin Diaz for a more detailed explanation)
function Queue() {
this._methods = [];
this._response = null;
this._flushed = false;
}
(function(Q){
Q.add = function (fn) {
if (this._flushed) fn(this._response);
else this._methods.push(fn);
}
Q.flush = function (response) {
if (this._flushed) return;
this._response = response;
while (this._methods[0]) {
this._methods.shift()(response);
}
this._flushed = true;
}
})(Queue.prototype);
You simply create a new instance of Queue, add the callbacks you need, and then flush the queue with the async response.
var queue = new Queue();
queue.add(function(results){
for (var result in results) {
// normal loop operation here
}
});
someFunction(param1, param2, function(results) {
queue.flush(results);
}
An added benefit of this pattern is that you can add multiple functions to the queue instead of just one.
If you have an object which contains iterator functions, you can add support for this queue behind the scenes and write code which looks synchronous, but isn't:
MyClass.each(function(result){ ... })
simply write each to put the anonymous function into the queue instead of executing it immediately, and then flush the queue when your async call is complete. This is a very simple and powerful design pattern.
P.S. If you're using jQuery, you already have an async method queue at your disposal called jQuery.Deferred.