2012-11-21 4 views
10

अस्वीकार करते हैं, और अगर उनमें से एक असफल, 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); 

चेक this jsfiddle

शायद यह सामान्य व्यवहार है। लेकिन, इस मामले में, मैं अपनी श्रृंखला के अंत को कैसे पकड़ सकता हूं भले ही उनमें से कुछ विफल हो जाएं?

उत्तर

11

यह डिजाइन द्वारा बताया गया है: विधि अपने गुरु सब 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/

+0

धन्यवाद @ यूरी-tarabanko! मुझे jQuery का विस्तार करने और सभी डिफेंडर अंत को देखने के लिए एक पुन: प्रयोज्य विधि जोड़ने का विचार पसंद है, भले ही वे विफल हो जाएं। आपके विचार के आधार पर और "कब" jQuery स्रोत पर, मैंने "कब" फिर से किया, यदि आपके पास समय है http://jsfiddle.net/cSy2K/5/;) – zazabe

1

हाँ, यह सामान्य व्यवहार है। यदि कोई विफल रहता है, तो वह चीज जो सभी पर निर्भर करती है वह भी विफल हो जाती है। jQuery docs भी देखें।

तो, आप या तो उन्हें मैन्युअल रूप से ट्रैक करने के लिए है, या आप 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 कॉलबैक कॉल करेंगे जब सभी वादे कार्रवाई की जाती है, और यह होगा स्थिति और उनके परिणाम का संकेत देने वाली वस्तुओं की एक सरणी प्राप्त करें।

संबंधित मुद्दे