我正在使用$.when链接一些延迟对象,如果其中一个失败,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); 检查this jsfiddle。
也许这是正常的行为。但是,在这种情况下,即使其中一些失败了,我如何才能抓住链的末端呢?
发布于 2012-11-21 20:41:16
这是经过设计的:该方法将在所有延迟解析后立即解析其主延迟,或者在延迟的one被拒绝时拒绝延迟的主延迟。..。请注意,在这一点上,一些延迟可能仍然是未解析的。
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();
};http://jsfiddle.net/cSy2K/2/
发布于 2012-11-21 22:12:16
是的,这是正常的行为。如果其中一个失败了,依赖于所有的东西也会失败。另请参阅jQuery docs。
因此,您要么必须手动跟踪它们,要么只将已解析的Promise提供给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回调,并且它将获得一个对象数组,指示它们的状态和结果。
https://stackoverflow.com/questions/13493084
复制相似问题