2012-11-24 23 views
6

मेरे पास कुछ है (कहें 5) AJAX अनुरोध जो मैं jQuery.ajax फ़ंक्शन का उपयोग कर एक ही समय में चलाता हूं।jQuery AJAX और "कब" फ़ंक्शन

अब मैं अपने परिणामों को सिंक्रनाइज़ और समेकित करना चाहता हूं और मैंने इसे प्राप्त करने के लिए jQuery.when फ़ंक्शन का उपयोग किया।

मेरी समस्या यह है कि $.when अनुरोधों में से एक के रूप में जल्द ही विफल हो जाता है और दूसरों को सफल होने पर भी लौटने से रोकता है।

मैं अपने सभी AJAX अनुरोधों (जो असफल रहा और सफल होने वाले सभी परिणामों से सिंक्रनाइज़ और सभी परिणाम कैसे प्राप्त कर सकता हूं)?

+1

यदि आप अपना वर्तमान कोड पोस्ट करते हैं तो यह आपकी मदद करेगा .. – Nelson

उत्तर

0

कार्यशील डेमो: http://jsbin.com/ocawoj/4/edit

function waitForAllPromisesToFinish() { 
    var i, 
     responses = [], 
     deferred = $.Deferred(), 
     helpers = { 
      addToResponses: function (index, data) { 
       responses[index] = data; 

       var i = 0, 
        isAnyNull = false; 

       for (i = 0; i < responses.length; i++) { 
        if (responses[i] === null) { 
         isAnyNull = true; 
         break; 
        } 
       } 

       if (isAnyNull === false) { 
        deferred.resolve(responses); 
       } 
      }, 
      setupPromise: function (promise, index) { 
       promise.always(function() { 
        var args = Array.prototype.slice.call(arguments); 
        helpers.addToResponses(index, args); 
       }); 
      } 
     }, 
     ajaxPromises = Array.prototype.slice.call(arguments); 

    for (i = 0; i < ajaxPromises.length; i++) { 
     responses[i] = null; 
    } 

    for (i = 0; i < ajaxPromises.length; i++) { 
     helpers.setupPromise(ajaxPromises[i], i); 
    } 

    return deferred.promise(); 
} 

फ़ंक्शन एक वादा करता है। आप एक किए गए हैंडलर को आपके द्वारा प्रदान किए गए एक से थोड़ा अलग संलग्न करते हैं।()। समारोह प्रत्येक AJAX वादे के जवाबों का ट्रैक रखता है। जब भी यह पता चलता है कि सभी AJAX वादे डेटा लौटा चुके हैं, या तो सफलता या विफलता, यह वादा को हल करेगा।

इसे प्राप्त करने के लिए और अधिक कुशल तरीके हो सकते हैं, हालांकि यह पहला है जिसे मैंने सोचा था।

+0

हाय! ऐसा लगता है कि यह वही करता है जो मैं ढूंढ रहा हूं! लेकिन ईमानदार होने के लिए मैं गुप्त रूप से ऐसा करने के लिए और अधिक "मानक" तरीका की उम्मीद कर रहा था क्योंकि मैंने सोचा था कि मैं इस तरह की समस्या को हल करने की कोशिश कर पृथ्वी पर पहला व्यक्ति नहीं हूं। वैसे भी, आपके श्वसन और समय के लिए धन्यवाद! :) –

+0

मैं अभी '$ .when' के कोड से गुजर चुका हूं और मैंने जो किया है वह' $ .when' के समान ही है। अंतर '$ है। जब' deferred.reject' कॉल करता है तो किसी भी चूक में विफल रहता है। यह समझ में आता है क्योंकि अन्यथा आप कैसे जानते हैं कि कोई भी स्थगित विफल रहा है? आपको यह सुनिश्चित करने के लिए प्रत्येक स्थगित राहत का श्वास जांचना होगा कि क्या यह सफलता का राहत है या विफलता है। आप इसे अपने बग ट्रैकर पर टिकट के रूप में उठा सकते हैं और शायद आपको कुछ फीडबैक मिल सकता है कि कोर टीम को यह कैसे पता होना चाहिए कि इसे कैसे संबोधित किया जाना चाहिए। –

+0

मैं मानता हूं कि यह एक बग नहीं है, '$।' इस तरह से काम करता है, यह समझ में आता है और यह ठीक है। मुझे लगता है, यह केवल सुविधा की कमी है क्योंकि ऐसे कई मामले हैं जहां हमें एक प्रकार का 'कब सभी' फ़ंक्शन चाहिए जो सभी परिणामों को सिंक्रनाइज़ करता है चाहे वे सफल हों या नहीं। मुझे यह कहना है कि मुझे आश्चर्य है कि बॉक्स या वर्कअराउंड ("मानक" जिस तरह से मैंने इसे पहले कहा था) से ऐसा कोई फ़ंक्शन उपलब्ध नहीं है। –

0

आप एक, दो या तीन अद्यतन कार्यों को परिभाषित कर सकता है (क्या आप क्या करना चाहते पर निर्भर करता है) कि इसी वादे (ajax कॉलबैक) की प्रतिक्रिया लेने के लिए:

function bindPromises(updateSuccess, updateFail, updateAnyway) { 
    var arrPromises = []; 

    // automate the promise retrieval if you want, that's up to you. 
    arrPromises[0] = ajaxRequest1(); 
    arrPromises[1] = ajaxRequest2(); 
    arrPromises[2] = ajaxRequest3(); 
    arrPromises[3] = ajaxRequest4(); 
    arrPromises[4] = ajaxRequest5(); 

    for(var j = 0; j < arrPromises.length; j++) { 
     arrPromises[j].then(updateSuccess, updateFail, updateAnyway); 
    } 
} 

या आप भी स्वचालित करने के लिए अधिक:

function bindPromises(arrayOfAjaxCalls, updateSuccess, updateFail, updateAnyway) { 
    var arrPromises = []; 

    for(var i = 0; i < arrayOfAjaxCalls.length; i++) { 
     arrPromises[i] = (arrayOfAjaxCalls[i])(); 
     arrPromises[i].then(updateSuccess, updateFail, updateAnyway); 
    } 
} 

आप वादे से परिचित नहीं हैं मैं उस विषय को कवर करने के लिए एक महान लेख के लिए आप बात करने के लिए करना चाहते हैं: Understanding jQuery.Deferred and Promise

+0

हाय, अगर मैं गलत हूं तो मुझे सही करें लेकिन ऐसा लगता है कि आपका कोड प्रत्येक AJAX प्रतिक्रिया के लिए प्रत्येक कॉलबैक निष्पादित करता है? जो मैं देख रहा हूं वह एक समाधान है जहां एक विधि केवल एक बार निष्पादित की जाएगी जब सभी अनुरोध समाप्त हो जाएंगे (इससे कोई फर्क नहीं पड़ता कि वे सभी सफल होते हैं या नहीं)। इस विधि से मुझे सभी AJAX कॉल प्रतिक्रियाएं प्राप्त करने में सक्षम होना चाहिए (जो विफल और सफल होते हैं)। –

+0

नहीं, आप सही हैं। लेकिन मुझे यकीन नहीं था कि आप तब तक इंतजार करना चाहते थे जब तक कि सभी कॉल खत्म न हो जाएं या प्रत्येक कॉल समाप्त होने के बाद कुछ कार्रवाई करने का फैसला करें। स्पष्ट रूप से अब आपके पास दोनों दृष्टिकोणों के लिए उदाहरण हैं;) – nirazul