With a custom object
function DeferredAjax(opts) {
this.options=opts;
this.deferred=$.Deferred();
this.country=opts.country;
}
DeferredAjax.prototype.invoke=function() {
var self=this, data={country:self.country};
console.log("Making request for [" + self.country + "]");
return $.ajax({
type: "GET",
url: "wait.php",
data: data,
dataType: "JSON",
success: function(){
console.log("Successful request for [" + self.country + "]");
self.deferred.resolve();
}
});
};
DeferredAjax.prototype.promise=function() {
return this.deferred.promise();
};
var countries = ["US", "CA", "MX"], startingpoint = $.Deferred();
startingpoint.resolve();
$.each(countries, function(ix, country) {
var da = new DeferredAjax({
country: country
});
$.when(startingpoint ).then(function() {
da.invoke();
});
startingpoint= da;
});
Fiddle http://jsfiddle.net/7kuX9/1/
To be a bit more clear, the last lines could be written
c1=new DeferredAjax( {country:"US"} );
c2=new DeferredAjax( {country:"CA"} );
c3=new DeferredAjax( {country:"MX"} );
$.when( c1 ).then( function() {c2.invoke();} );
$.when( c2 ).then( function() {c3.invoke();} );
With pipes
function fireRequest(country) {
return $.ajax({
type: "GET",
url: "wait.php",
data: {country:country},
dataType: "JSON",
success: function(){
console.log("Successful request for [" + country + "]");
}
});
}
var countries=["US","CA","MX"], startingpoint=$.Deferred();
startingpoint.resolve();
$.each(countries,function(ix,country) {
startingpoint=startingpoint.pipe( function() {
console.log("Making request for [" + country + "]");
return fireRequest(country);
});
});
http://jsfiddle.net/k8aUj/1/
Edit : A fiddle outputting the log in the result window http://jsfiddle.net/k8aUj/3/
Each pipe call returns a new promise, which is in turn used for the next pipe. Note that I only provided the sccess function, a similar function should be provided for failures.
In each solution, the Ajax calls are delayed until needed by wrapping them in a function and a new promise is created for each item in the list to build the chain.
I believe the custom object provides an easier way to manipulate the chain, but the pipes could better suit your tastes.
Note : as of jQuery 1.8, deferred.pipe()
is deprecated, deferred.then
replaces it.