2013-02-22 53 views
12

मेरे पास तीन फ़ंक्शन हैं जिन्हें मैं चलाने की कोशिश कर रहा हूं, पहले दो कुछ एसिंक सामग्री कर रहे हैं जिन्हें तीसरे उपयोग के लिए डेटा की आवश्यकता है। मैं चाहता हूं कि तीसरा कार्य केवल तभी आग लग जाए जब 1 और 2 दोनों किया जाता है। यह सामान्य संरचना है लेकिन अंतिम कार्य 1 और 2 खत्म होने से पहले फायरिंग कर रहा है। return d.promise();:jquery कस्टम स्थगित फ़ंक्शन

function run() { 
    var data1 = {}; 
    var data2 = {}; 

    $.when(first(), second()).done(constructData()); 

    function first() { 
     var d = new $.Deferred(); 

     //do a bunch of stuff async 
     data1 = {}; 

     d.resolve(); 
    } 
    function second() { 


     var d = new $.Deferred(); 

     //do a bunch of stuff async 
     data2 = {}; 
     d.resolve(); 
    } 
    function constructData() { 
     //do stuff with data1 and data2 
    } 

} 

उत्तर डेटा तुरंत

$.when(first(), second()).done(constructData); 

उत्तर

23

आपको वादा वस्तु वापस करनी चाहिए। आप भी इस लाइन में एक त्रुटि है:

$.when(first(), second()).done(constructData()); 

यह

$.when(first(), second()).done(constructData); // don't call constructData immediately 

तो सब एक साथ होना चाहिए यह हो सकता है:

function run() { 
    var data1 = {}; 
    var data2 = {}; 

    $.when(first(), second()).done(constructData); 

    function first() { 
     return $.Deferred(function() { // <-- see returning Deferred object 
      var self = this; 

      setTimeout(function() { // <-- example of some async operation 
       data1 = {func: 'first', data: true}; 
       self.resolve();  // <-- call resolve method once async is done 
      }, 2000); 
     }); 
    } 
    function second() { 
     return $.Deferred(function() { 
      var self = this; 
      setTimeout(function() { 
       data2 = {func: 'second', data: true}; 
       self.resolve(); 
      }, 3000); 
     }); 
    } 
    function constructData() { 
     //do stuff with data1 and data2 
     console.log(data1, data2); 
    } 
} 

http://jsfiddle.net/FwXZC/

+0

ने निर्माण डेटा को कॉल नहीं किया, तुरंत चाल धन्यवाद! – Brian

+0

वाह, यह नहीं पता था कि इस तरह से फ़ंक्शन को स्थगित वस्तु के अंदर लिखा जा सकता है, धन्यवाद! – Denis

+0

@ डेनिस मुझे नहीं लगता कि यह करने का उचित तरीका है। JQuery [डॉक्स] के अनुसार (https://api.jquery.com/jquery.deferred/): 'preStart' पैरामीटर _" एक फ़ंक्शन है जिसे कन्स्ट्रक्टर रिटर्न से ठीक पहले कहा जाता है। "_। इसलिए स्थगित ऑब्जेक्ट बनने से पहले फ़ंक्शन को कॉल किया जाता है। –

1

मुझे लगता है कि आप first() होनी चाहिए और second() एक वादा वापसी का निर्माण फोन नहीं किया गया था। docs से:

एक भी तर्क jQuery.when को पारित कर दिया है और यह नहीं है, तो एक स्थगित या एक वादा है, यह के रूप में एक स्थगित हल हो गई है और किसी भी संलग्न doneCallbacks तुरंत क्रियान्वित की जाएगी माना जाएगा।

मैं ऐसा क्यों when कॉल constructData बहुत जल्दी बुला रहा है हो सकता है संदेह है।

कोड से आपको बताना मुश्किल है, लेकिन सुनिश्चित करें कि एसिंक ऑपरेशन पूरा होने के बाद आप d.resolve() पर कॉल कर रहे हैं।

आपको लगता है कि एक और अधिक प्राकृतिक दृष्टिकोण स्पष्ट रूप से data1 और data2 की स्थापना करने के लिए मिल सकती है डेटा है कि जब resolve कहा जाता है की आपूर्ति का उपयोग करने के बजाय है। इसका मतलब यह होगा कि आपके when कॉल कुछ इस तरह दिखेगा:

$.when(first(), second()).done(function(result1, result2) { 
    data1 = result1[0]; 
    data2 = result2[0]; 

    constructData(); 
}); 

ध्यान दें कि done विधि को आपूर्ति परिणामों की सही प्रारूप टाल वस्तुओं की प्रकृति पर निर्भर करता है। यदि वादे से $.ajax पर वादे वापस लौटाए जाते हैं, तो परिणाम [data, statusText, jqXhrObject] के रूप में होना चाहिए।

+0

हाँ मैं नहीं जोड़ा था, एसिंक कोड के सभी यह कस्टम गैर jquery AJAX अनुरोधों का एक गुच्छा है, त्रुटि यह थी कि मैंने कैसे किया गया कार्य – Brian