С пользовательским объектом
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/
Чтобы быть немного более понятным, последние строки могут быть написаны
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();} );
С трубами
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/
Редактировать: Скрипка, выводящая журнал в окне результатов http://jsfiddle.net/k8aUj/3/
Каждый вызов канала возвращает новое обещание, которое, в свою очередь, используется для следующего канала.Обратите внимание, что я предоставил только функцию sccess, аналогичная функция должна быть предусмотрена для сбоев.
В каждом решении вызовы Ajax откладываются до тех пор, пока это не требуется, оборачивая их в функцию, и для каждого элемента создается новое обещаниев списке, чтобы построить цепочку.
Я считаю, что пользовательский объект обеспечивает более простой способ управления цепочкой, но трубы могут лучше соответствовать вашим вкусам.
Примечание : по состоянию на jQuery 1.8, deferred.pipe()
устарело, deferred.then
заменяет его.