Reputation: 3460
I have been researching jquery deferred objects for a while now and I'm stumped on one thing.
The "done," "always," "then," etc methods take, as their arguments, functions which should be called when the deferred object is resolved.
However I tried chaining requests by passing a deferred object into the "always" method, and that seems to work too:
// A is an array of data
var req = ajax(url + "?d=" + A[0]).done(processResults).fail(reportFailure);
for (var i = 1 ; i < A.length ; i++) {
var tmp = ajax(url + "?d=" + A[i]).done(processResults).fail(reportFailure);
req.always(tmp);
req = tmp;
}
However, it doesn't really work. Because when I follow the above code with this:
req.always(foobar);
foobar seems to get called at some random time, not necessarily after the last element in the array is processed.
Would it be better to use when?
// A is an array of data
var req = $.when(ajax(url + "?d=" + A[0]).done(processResults).fail(reportFailure));
for (var i = 1 ; i < A.length ; i++) {
req = $.when(req, ajax(url + "?d=" + A[i]).done(processResults).fail(reportFailure));
}
req.always(foobar);
Would the above code (using "when") result in the ajax requests happening one after the other, or would they occur simultaneously?
I looked into chaining with "pipe" by the way, but because of scoping issues I think it would be harder to use "pipe" with a for loop as above.
Also, why does the original code "almost work"? What is happening there? Is it executing the deferred object as if it were a function, and what happens when it does that?
Upvotes: 3
Views: 471
Reputation: 4670
You should build an array and use javascript apply :
//create an array of one deferred per element
var requests = $.map(A, function(index, a){return= $.ajax(url + "?d=" + a);});
//merge all deferreds into a single one
var mergedRequest = $.when.apply(null, requests);
mergedRequest.done(function(res0, res1, ...){
//your code goes here
//if you want results as an array just use arguments
arguments.length == A.length;
});
EDIT: If you want your calls to be made serially do :
var result = $.ajax(url + "?d=" + A[0]);
for (var i = 1 ; i < A.length ; i++) {
result = result.pipe(function() {
return $.ajax(url + "?d=" + a[i]);
}
}
result.done(processResults).fail(reportFailure);
Upvotes: 2