Reputation: 1862
If I have a backbone collection that has a method that calls an asynchronous method on each of its models like this:
getStatus: function() {
this.each(function(model) {
model.getStatus();
});
}
And in the model class, an asynchronous ajax call is made like this:
getStatus: function() {
$.ajax({
//ajax properties here
});
}
How can I determine when each and every model has completed it's asynchronous call (not necessarily successfully) and returned?
So in my collection, I need a getStatusSuccess
method that executes after all these asynchronous calls have been completed. I have looked into jQuery deferreds, and I have tried a few things to get it to work, but to no avail. However, I still believe that it can be solved using deferreds.
Upvotes: 1
Views: 176
Reputation: 1029
Can suggest two ways to defer a call:
$.when()
construction, which is perfectly described above by nikoshr_.after(count, function)
method, which takes basically two arguments: amount of asynchronous calls and your call to defer.Upvotes: 0
Reputation: 33364
$.ajax
returns a Deferred objectyou can combine Deferred objects with jQuery.when
to produce a "master" Deferred
In the case where multiple Deferred objects are passed to jQuery.when, the method returns the Promise from a new "master" Deferred object that tracks the aggregate state of all the Deferreds it has been passed.
The method will resolve its master Deferred as soon as all the Deferreds resolve, or reject the master Deferred as soon as one of the Deferreds is rejected.
Backbone proxies a lot of functions from Underscore on collections, notably _.invoke
which returns an array with the results of the calls
function.apply
will let you call a function with a given context and arguments provided as an arrayCombining all this :
var M = Backbone.Model.extend({
getStatus: function() {
return $.ajax({
// ...
});
}
});
var C = Backbone.Collection.extend({
model: M,
getStatus: function() {
var jqXHRs = this.invoke('getStatus');
return $.when.apply(this, jqXHRs);
}
});
var c = new C([
{id: 1},
{id: 2}
]);
c.getStatus().always(function() {
console.log('done');
});
And a demo http://jsfiddle.net/nKDjW/
Upvotes: 2
Reputation: 11337
Check my recent answer at Sequence of operation in Node.js.
Basically you could use Async.js. Check its parallel function..
Upvotes: 0