2015-04-16 9 views
5

एक कोणीय परियोजना के लिए, मुझे वादे घोंसला करना पड़ता है और मैं ऐसे मामलों में भाग लेता हूं जहां मुझे यकीन नहीं है कि मैं क्या कर रहा हूं।कोणीय सशर्त वादे

return Action1().then(function (data) { 
    var defer = $q.defer(); 
    if (data.condition) { 
     $q.all([Action2(), Action3(), Action4()]).then(function() { 
      defer.resolve(); 
     }); 
    } else { 
     defer.reject("error_code"); 
    } 
    return defer.promise; 
}); 

Action1, एक्शन 2, Action3 और Action4 काम कर रहे हैं वादे कार्य: यहाँ मेरी कोड में से एक है। यह बहुत सारे वादे और कार्य स्थितियों पर निर्भर करता है। क्या मैं ऐसा कर सकता हूं और सुनिश्चित कर सकता हूं कि मेरा मुख्य कार्य हमेशा हल हो जाएगा या खारिज कर दिया जाएगा?

मैंने पढ़ा है कि हम संकल्प समारोह के अंदर वादा पास कर सकते हैं। मुझे लगता है कि क्या करना है और इसके बाद के संस्करण के रूप में यह एक ही है सकते हैं:

return Action1().then(function (data) { 
    var defer = $q.defer(); 
    if (data.condition) { 
     defer.resolve($q.all([Action2(), Action3(), Action4()]); 
    } else { 
     defer.reject("error_code"); 
    } 
    return defer.promise; 
}); 

उत्तर

3

नहीं, यह नहीं है। Action2(), Action3() या Action4() में से एक "फेंक" और $q.all(…) वादा को अस्वीकार कर दिया गया है - तो आपका पहला फ़ंक्शन हमेशा के लिए लंबित रहेगा - आपका स्थगित कभी हल नहीं होता है। यह deferred antipattern का सबसे आम बग है जिसका आपने यहां उपयोग किया है।

आपका दूसरा फ़ंक्शन इसे कम करता है, लेकिन अभी भी अनावश्यक जटिल है। आपको यहां स्थगित करने की आवश्यकता नहीं है! बस वादा सीधे लौटने के लिए, और $q.reject का उपयोग करें:

return Action1().then(function (data) { 
    if (data.condition) { 
     return $q.all([Action2(), Action3(), Action4()]); 
    } else { 
     return $q.reject("error_code"); 
    } 
}); 

या, जैसा कि यह एक then हैंडलर के अंदर होता है, आप भी throw "error_code" उपयोग कर सकते हैं।

+0

आपने अपना उत्तर संपादित किया। मैं दूसरे भाग के लिए पूछ रहा था लेकिन जब आप पोस्ट कर रहे थे तो आप इसका उत्तर देते थे। मैं वादे के साथ एक नौसिखिया हूँ। मैं फॉर्म (संकल्प और अस्वीकार के साथ स्थगित) सीखता हूं और मैं इसे हर जगह अपने प्रोजेक्ट में उपयोग कर रहा था। धन्यवाद मुझे यह इंगित करने के लिए बहुत कुछ है कि मैं सीधे $ q का उपयोग कर सकता हूं या त्रुटि फेंक सकता हूं। – JeromeModi

1

आपके उत्तर के लिए धन्यवाद, मैं पहली कोड संस्करण में अपनी त्रुटि देख सकता हूं। मुझे लगता है कि यह q.all है जो मुझे परेशान करता है।

मैंने स्थगित एंटीपार्टर्न पढ़ा। यह कहा गया है कि हमें किसी भी कारण से स्थगित वस्तुओं को बनाने की ज़रूरत नहीं है।

return Action1().then(function() { 
    return $q.all([Action2(),Action3(), Action4()]);   
}); 

लेकिन अगर (data.condition) की वजह से मैं यह नहीं कर सकते:

सरल मामले इस है। क्या मेरा दूसरा कोड ऐसा करने का एकमात्र तरीका है? क्या मैं किसी मामले में हूं या मुझे डिफर का उपयोग करना है?

यह "promisification" के बारे में बोलता है, लेकिन कोणीय के साथ मुझे नहीं पता कि यह एक अच्छी बात है (libs unmaintained लग रहा है)।

चीयर्स,

+0

हां, आपको केवल प्रोमोसिफिकेशन के लिए स्थगित का उपयोग करना चाहिए। हालांकि कोणीय में, दो सबसे अधिक उपयोग किए जाने वाले एसिंक विधियों '$ http' और' $ टाइमआउट 'पहले से ही वादे वापस करते हैं, इसलिए आपको शायद ही कभी इसकी आवश्यकता होती है। – Bergi

+0

कोणीय 1.3 में, मैंने देखा कि वे $ q कन्स्ट्रक्टर के लिए एक नया वाक्यविन्यास प्रस्तुत करते हैं। आप इसके बारे में क्या सोचते हैं? क्या इसका उपयोग करने के लिए यह एक अच्छा अभ्यास है? – JeromeModi

+1

एक अधिकार, एक वादा कन्स्ट्रक्टर। हां, स्थगित होने की बजाय इसका उपयोग करना अच्छा अभ्यास है, यह वादे के लिए नया मानक है। लेकिन "स्थगित antipattern" अभी भी वही है, शायद "वादा कन्स्ट्रक्टर antipattern" के रूप में। जब आप पहले से ही वादे के साथ काम करते हैं तो काम का उपयोग न करें। – Bergi

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