[英]jquery deferred - “always” called at the first reject
我正在使用$.when
鏈接一些Deferred對象,如果其中一個失敗,則在失敗后直接調用always
方法,即使我仍然有一個處於“掛起”狀態的延遲器。
var promises = [], defs = [];
for(var i=0 ; i < 10 ; i++){
defs.push($.Deferred());
promises.push(defs[i].promise());
}
var res = $.when.apply($, promises);
res.fail(function(){console.log('failed')});
res.done(function(){console.log('done')});
res.always(function(){console.log('always')});
res.then(function(){console.log('then, done')},
function(){console.log('then, failed')});
var j = 0;
var t = setInterval(function(){
if(j < 10){
if(j < 5) {
console.log('resolve');
defs[j++].resolve();
}
else {
console.log('reject');
defs[j++].reject();
}
}
else {
clearInterval(t);
}
}, 200);
檢查這個jsfiddle 。
也許這是正常行為。 但是,在這種情況下,即使其中一些失敗,我如何才能抓住我的鏈條的末端?
它的設計:該方法能夠解決它的主人,一旦延遲,因為所有Deferreds決心,或拒絕只要Deferreds的一個被拒絕延期的主人。 [...]請注意,此時某些延期可能仍未得到解決 。
http://api.jquery.com/jQuery.when/
您可以保存對所有延遲的引用並單獨跟蹤它們。
像這樣的東西:
var whenAll = function() {
var dfd = $.Deferred(),
len = arguments.length,
counter = 0,
state = "resolved",
resolveOrReject = function() {
if(this.state() === "rejected"){
state = "rejected";
}
counter++;
if(counter === len) {
dfd[state === "rejected"? "reject": "resolve"]();
}
};
$.each(arguments, function(idx, item) {
item.always(resolveOrReject);
});
return dfd.promise();
};
是的,這是正常行為。 如果一個失敗,依賴所有的東西也會失敗。 另請參閱jQuery文檔 。
所以,你要么必須手動追蹤它們,否則你只能送入解決承諾到when
:
promises.push( defs[i].promise().then(function(x) {
return {result:x,resolved:true};
}, function(x) {
return (new $.Deferred).resolve({result:x,resolved:false});
})
);
有了這個,你的res
只會在處理完所有的promises時調用done
回調,並且會得到一個指示狀態和結果的對象數組。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.