使用jQuery.when()
,如果一个请求失败,那么它们都会失败。
$.when(deferred1, deferred2).then(function() {
// Called only after both deferred are resolved
}, function() {
// Called immediately after one of the deferreds is rejected
});
你怎么能等待所有事情都执行甚至失败?我尝试使用.always()
而不是.then()
,但在第一次失败后也会立即调用回调。
一个(丑陋的)解决方案是在两个操作完成时控制标志并在每个操作上使用.always()
(没有$.when()
)。
var deferred1Complete = false;
var deferred2Complete = false;
function callback() {
if (deferred1Complete && deferred2Complete) {
// Execute after both deferred are either resolved or rejected
}
}
deferred1.always(function() {
deferred1Complete = true;
callback();
});
deferred2.always(function() {
deferred2Complete = true;
callback();
});
有更好的方法吗?
答案 0 :(得分:3)
了Jonatan,
我喜欢你的解决方案并提供一些改进:
以下是代码:
(function($) {
$.whenAlways = function(chain) {
if(!chain || !$.isArray(chain)) chain = $.extend([], arguments);
var n = chain.length;
return $.Deferred(function(deferred) {
$.each(chain, function(i, promise) {
if(!promise.always) n--;
else {
promise.always(function() {
deferred.notify(--n);
if(n == 0) deferred.resolve();
});
}
});
if(n == 0) deferred.resolve();
}).promise();
}
})(jQuery);
这种方法允许在任何chain
承诺被解决/拒绝时调用任何progressCallbacks(添加到重新调整的promise),而不管重新解析/拒绝顺序。通过将未完成的chain
承诺的数量传递给progressCallbacks,您可以提供倒计时指示或响应中间倒计时里程碑。
似乎工作 - DEMO
答案 1 :(得分:2)
另一种解决方案(不那么丑陋)就是将延迟.always()
回调链接起来。
deferred1.always(function() {
deferred2.always(function() {
// Execute after both deferred are either resolved or rejected
});
});
我写了一个小函数来处理这个问题:
function whenAlways() {
var chain = $.extend([], arguments);
return new $.Deferred(function(deferred) {
var callback = function() {
if (chain.length == 0) {
deferred.resolve();
return;
}
var object = chain.shift();
$.when(object).always(callback);
};
callback();
}).promise();
}
用法:
whenAlways(deferred1, deferred2)
.done(function() {
// Execute after both deferred are either resolved or rejected
});