2011-06-06 15 views
6

तो jQuery deferreds और $.when का उपयोग समानांतर में कई ऑब्जेक्ट्स लोड करने के लिए।सफलता में jquery स्थगित मोड़ विफलता

$.when(
    a.ajax(), b.ajax(), c.ajax() 
).then(
    //do something when all are complete 
    complete(); 
); 

अब, b.ajax() कभी-कभी असफल हो जाएगा, लेकिन मुझे वास्तव में परवाह नहीं है। मैं सिर्फ तब तक इंतजार करना चाहता हूं जब तक कॉल पूरी होने से पहले सभी कॉल पूरी नहीं हो जातीं()।

दुर्भाग्यवश, जैसे ही b विफल रहता है, when() अस्वीकार करता है, और then() कॉलबैक को कभी भी नहीं चलाता है। यह $.when() के लिए AFAIK अपेक्षित व्यवहार है, हालांकि इस मामले में मुझे सूट है।

मैं प्रभावी रूप से एक तरह से कहना चाहता हूँ:

$.when(
    a.ajax(), b.ajax().fail(return success), c.ajax() 
).then(...) 

या शायद when(), या एक अधिक उपयुक्त निर्माण का उपयोग करने के लिए एक अलग तरीके है?

$.onCompleteSucceed = function(oldDfd) { 
    var newDfd = $.Deferred(); 

    oldDfd.always(newDfd.resolve); 

    return newDfd.promise(); 
} 

फिर आप इस विधि में उपयुक्त कॉल लपेट सकता है::

+0

@Ates मुझे लगता है कि आपके हटाए गए उत्तर को वापस लौटने से पहले उस नए स्थगित ऑब्जेक्ट को हल करके ठीक किया जा सकता है। – Alnitak

+0

संभावित डुप्लिकेट [$। डिफर्ड: जब हर वादा निष्पादित किया गया है तो कैसे पता लगाया जाए] (http://stackoverflow.com/q/19177087/1048572) – Bergi

उत्तर

1

तो मैं इसे बाहर अंत में लगा, एक ही मुद्दे के साथ किसी और को मेरा जवाब देखें:

how to fool jqXHR to succeed always

लोन्सोमेडे का जवाब साफ था, लेकिन काफी कुछ नहीं था जो मैं बाद में था।

+0

jQuery 1.8 के रूप में, पाइप को बहिष्कृत किया गया है। [JQuery Deferred] में लिखना देखें (https://api.jquery.com/deferred.then/)। – Griffin

1

आप $.Deferred वस्तु लपेटकर द्वारा काफी आसानी से बना सकते हैं $.onFailSucceed

$.when(
    a.ajax(), $.onCompleteSucceed(b.ajax()), c.ajax() 
).then(...) 
+0

अच्छा समाधान, सिवाय इसके कि यह 'बी के परिणाम को पारित नहीं करेगा .ajax() '' .then() 'हैंडलर में। – Alnitak

3

सफलता में विफलता को हैक करने से बेहतर कुछ बेहतर है।

छोटे ज्ञात तथ्य, $ .when() पैरामीटर विफल होने पर तत्काल() कॉलबैक निष्पादित करेगा। यह डिजाइन द्वारा है। प्रलेखन के शब्दों में:

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

बहु-Deferreds मामले में जहां Deferreds में से एक को अस्वीकार कर दिया गया है, jQuery.when तुरंत अपने गुरु स्थगित के लिए failCallbacks सक्रिय करता है। ध्यान दें कि कुछ बिंदुओं को अभी भी उस बिंदु पर अनसुलझा किया जा सकता है। यदि आपको इस मामले के लिए अतिरिक्त प्रसंस्करण करने की आवश्यकता है, जैसे कि किसी भी अधूरा AJAX अनुरोधों को रद्द करना, आप अंतर्निहित jqXHR ऑब्जेक्ट्स को बंद करने में रोक सकते हैं और विफल/जांच में उन्हें रद्द/रद्द कर सकते हैं।

वास्तव में प्रतीक्षा करने का कोई अंतर्निहित तरीका नहीं है जब तक कि वे सभी सफलता/विफलता की स्थिति के बावजूद समाप्त नहीं हो जाते।

तो, मैंने एक $ बनाया।whenAll() आप :) यह हमेशा जब तक उन सभी को हल इंतजार कर रहा है, एक ही रास्ता या अन्य के लिए:

http://jsfiddle.net/InfinitiesLoop/yQsYK/

+1

इसके लिए धन्यवाद। – tomswift

5

आप एक वादा की विफलता को पकड़ने और एक सफलता के लिए कि परिवर्तित करना चाहते हैं, तो आप कर सकते हैं एक संकल्प लिया वादा वापस जाने के लिए है, तो जैसे then की failFilter का उपयोग करें:

deferredCall.then(function(answer) { 
    // this is success. you might transform the answer here. 
    return transformed; 
}, function() { 
    // this is a fail. you might resolve the fail with an empty object. 
    return $.Deferred().resolve({}).promise(); 
}); 

ऐसा करने से यह सुनिश्चित होगा कि श्रृंखला विफलता अटूट अतीत जारी रख सकते हैं।

तो, आपके उदाहरण के लिए, यदि आप ऐसा करते हो सकता है:

$.when([ 
    a.ajax(), 
    b.ajax().then(function(answer) { 
     return answer; 
    }, function() { 
     return $.Deferred().resolve({}).promise(); 
    }), 
    c.ajax() 
]).then(function(results) { 
    // etc. 
}); 

उदाहरण 2: मेरी अनुप्रयोगों में, मैं कभी कभी then का उपयोग एक विशेष इकाई के लिए संबंधपरक डेटा प्राप्त करने के लिए और करने के लिए एक 404 की संभावना के लिए अनुमति संकेत मिलता है कि इस तरह का कोई संबंध मौजूद है:

getEntity(id).then(function(entity) { 
    return getAssociation(id).then(function(association) { 
     entity.association = association; 
     return entity; 
    }, function() { 
     entity.association = null; 
     return $.Deferred().resolve(entity).promise(); 
    }); 
}).done(function(entity) { 
    // etc. 
}); 

ध्यान दें, पुराने जवाब pipe विधि का उपयोग कर सुझाव देते हैं। यह विधि jQuery 1.8 के रूप में बहिष्कृत है।

+0

कोई विचार यह क्यों काम नहीं करेगा? मैंने कोशिश की और यह अभी भी पाइप – Andrey

+0

के विफलता मामले में चला गया है यह महत्वपूर्ण है कि आपका असफल हैंडलर ("तब" का दूसरा कार्य) एक हल किए गए वादे को वापस कर दे। एक असफल वादा या किसी भी मूल्य से कोई वादा नहीं, श्रृंखला को एक और असफल हैंडलर के माध्यम से जारी रखने की अनुमति देगा। – Griffin

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