when I have a variable number of ajax requests, how can I call them using deferreds?
my guess:
//qty_of_gets = 3;
function getHTML(productID, qty_of_gets){
var dfd = $.Deferred(),
i = 0,
c = 0;
//this is where there could be some magic to
//do multiple ajax posts
//obviously I'm out of my depth here...
while (i <= qty_of_gets){
dfd.pipe(function(){
$.get("queries/html/" + product_id + i + ".php");
});
i++
}
dfd.done(function(){
while (c <= qty_of_gets){
$('myDiv').append(c);
c++;
}
});
}
If you want to execute the Ajax calls sequentially, you have to return the promise from the callback and also attach a new callback to the last promise object:
var dfd = $.Deferred(),
promise = dfd.promise(),
i = 0,
c = 0;
while (i <= qty_of_gets) {
// needs an IIFE
(function(i)
promise = promise.then(function(){
return $.get("queries/html/" + product_id + i + ".php");
});
}(i++));
}
promise.done(function(){
while (c <= qty_of_gets){
$('myDiv').append(c);
c++;
}
});
// resolve deferred
dfd.resolve();
As of jQuery 1.8, you should use .then
instead of .pipe
.
Another problems is (in your example at least) that at the time the callbacks are executed, i
won't have the value you expect. You can use an immediately invoked function expression to capture the current value of i
. See JavaScript closure inside loops – simple practical example for more info.
There is no clean solution for getting the results. I think the best you could do is adding the results to an array and access that array in the .done
callback. I.e.:
var results = [];
while (i <= qty_of_gets) {
// needs an IIFE
(function(i)
promise = promise.then(function(){
return $.get("queries/html/" + product_id + i + ".php")
.then(function(result) {
results[i] = result;
});
});
}(i++));
}
promise.done(function(){
// do something with `results`
});
Close, you need to return a promise object from the .pipe
callback.
See felix's answer, the next sample has additional issues than just the return missing.
dfd.pipe(function(){
return $.get("queries/html/" + product_id + i + ".php");
});
also, I don't think it's actually written anywhere yet, but .pipe
is implemented like this in the core in recent versions:
promise.pipe = promise.then
therefore, you could should replace dfd.pipe
with dfd.then
Reference: http://api.jquery.com/deferred.pipe/
An alternative as adeneo mentioned is to use $.when
function getHTML(productID, qty_of_gets) {
var dfdArr = [];
while (i <= qty_of_gets) {
dfdArr.push($.get("queries/html/" + product_id + i + ".php"));
i++
}
$.when.apply(null, dfdArr).done(function () {
for (response in arguments) {
$('#myDiv').append(response[0]);
}
});
}