jQuery的延迟 - “永远”之称的第1拒收(jquery deferred - “always”

2019-08-03 01:33发布

我使用$.when到链递延一些对象,如果其中一个出现故障,将always方法将直接失败后调用,即使我仍然处于“待定”状态的一些deferrer。

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 。

也许这是正常行为。 但是,在这种情况下,我怎么能抓住我的链条,即使他们中的一些已经失败结束了吗?

Answer 1:

它的设计:该方法能够解决它的主人,一旦延迟,因为所有Deferreds决心,或拒绝只要Deferreds的一个被拒绝延期的主人。 [...]请注意,一些Deferreds的可能仍然是在这一点上没有得到解决

http://api.jquery.com/jQuery.when/

您可以保存所有deferreds参考,并分别对其进行跟踪。

事情是这样的:

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/



Answer 2:

是的,这是正常的行为。 如果一个失败,它依赖于所有的事情也将失败。 又见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只会调用done回调时,所有的承诺进行处理,并且将获得表示状态和他们的结果对象的数组。



文章来源: jquery deferred - “always” called at the first reject