2016-03-08 25 views
11

का उपयोग करते समय वादा श्रृंखला का वादा करना मैं वादा एपीआई और चेनिंग को समझने की कोशिश कर रहा हूं, विशेष रूप से समय $timeout.then() के साथ उपयोग किया जाता है। मैंने निम्न से क्या उम्मीद की थी कि $timeout एक वादा देता है, .then() इसे हल होने तक नहीं बुलाया जाएगा।

लेकिन एबीएबी के बजाय, यह हर समय एबीबीए है।

मैं यह सुनिश्चित करने के लिए वादा एपीआई का उपयोग कैसे कर सकता हूं कि लंबी अवधि के कॉल (या $timeout का उपयोग करके देरी कॉल) .then() निष्पादित होने से पहले वास्तव में पूर्ण हो जाती है?

कोड

angular 
    .module('app', []) 
    .controller('ThenCtrl', ThenCtrl); 

function ThenCtrl($timeout, $q) { 
    var vm = this; 

    vm.items = []; 

    $q.when(pushA()).then(pushB()); 

    $timeout(pushA, 5000).then(pushB()); 

    function pushA() { 
    vm.items.push('A'); 
    } 

    function pushB() { 
    vm.items.push('B'); 
    } 
} 

मार्कअप

<div ng-app="app"> 
    <div ng-controller="ThenCtrl as vm"> 
    {{vm.items}} 
    </div> 
</div> 

मैं एक बेला सेट कर लेते हैं: https://jsfiddle.net/kan3c61t/

उत्तर

13

.then तरीकों के अंदर कार्यों आह्वान न आया था।

$q.when(pushA()).then(pushB); 
    //$q.when(pushA()).then(pushB()); 

    $timeout(pushA, 5000).then(pushB); 
    //$timeout(pushA, 5000).then(pushB()); 

इसके बजाय कार्यों को .then विधि के तर्क के रूप में पास करें। $q सेवा उन कार्यों को बाद में लागू करने के लिए रखेगी।

जिस तरह से $q सेवा कार्य करता है यह .then विधि का तर्क बाद में लागू किए जाने वाले फ़ंक्शन के रूप में संग्रहीत करता है। इस मामले में, $q सेवा pushB() द्वारा B को तुरंत सरणी पर धक्का देने के दुष्प्रभाव के साथ लौटाए गए मान को संग्रहीत कर रही थी।

DEMO on JSFiddle

+0

यह भी एक बहुत ही दिलचस्प समाधान है। –

+2

बहुत स्पष्ट रूप से कहा गया। उन मूलभूत जोड़ों में क्या अंतर हो सकता है। – twip

+0

इससे मुझे बहुत मदद मिली – Fergus

6

ये रहा। मैंने जो किया वह कोड के then भाग में success फ़ंक्शन को अनिवार्य रूप से जोड़ा गया है।

$timeout(pushA, 5000).then(function(success) { 
    pushB() 
    }); 

यहां काम कर रहे demo है।

तुम भी हालांकि इस जवाब के लिए खोज इस

$timeout(pushA, 5000).then(function(success) { 
    pushB() 
    },function(error){console.log("Error");}); 

की तरह एक error function जोड़ सकते हैं, मैं भी भर में यह बहुत ही helpful link

+1

यह अंतर्निहित API संरचना का एक उत्कृष्ट अनुस्मारक है; धन्यवाद। – twip

4

दूसरों का उल्लेख किया है के रूप में - अपने बड़ा मुद्दा है कि आप .then(promise) और नहीं .then(function)

वादे एक मूल्य + समय का प्रतिनिधित्व करते हैं। यह पहले से ही शुरू हो गया ऑपरेशन का परिणाम है। एक वादा एक मूल्य है - thenफ़ंक्शन के लिए प्रतीक्षा करता है। आप "एक और वादे के बाद वादा नहीं कर सकते" - एक वादा का मतलब है कि ऑपरेशन पहले ही शुरू हो चुका है।

जब आप then(x)फ़ंक्शन के अलावा किसी अन्य चीज़ के लिए इसे अनदेखा किया जाता है।वादे के नमूने में यह एक दुर्भाग्यपूर्ण विकल्प है लेकिन हमें इसके साथ रहना है।

चूंकि आपकी कॉल तुल्यकालिक हैं, इसलिए आपको इसके लिए वादे का उपयोग नहीं करना चाहिए। अपने कोड होता है, तो कुछ तुल्यकालिक आप ; साथ कार्यों और नहीं then क्रम सकते हैं:

pushA(); 
pushB(); 

यदि यह एक कॉल कि वादे देता तो यह सिर्फ हो जाता है:

pushA().then(pushB); 

वहाँ $q.when बुला का कोई मतलब नहीं है जो वादे के लिए गैर वादे बदलता है।

मैं इसे के रूप में लिखते हैं:

pushA(); 
$timeout(5000).then(pushB); 

एक वादा लौटने कार्य करने के लिए पहले तुल्यकालिक कार्रवाई कन्वर्ट करने के लिए या कहीं भी टाइमआउट को छोड़कर वादों को शामिल करने की कोई मतलब नहीं है। आप pushA की जरूरत है 5000ms के बाद होने की ही मैं अभी भी शायद लिखना चाहते हैं:

$timeout(5000).then(pushA).then(pushB) 

के बाद से मुझे लगता है कि इसे और अधिक पठनीय है और फिर हम pushA और pushB वादे के साथ सीधे शामिल नहीं है।

+0

प्रतिक्रिया के लिए धन्यवाद। एसओ पदों के लिए संक्षिप्त और स्पष्ट दोनों होने के दौरान कभी-कभी इरादे को अच्छी तरह से पकड़ना मुश्किल होता है। जो मैं कब्जा करने की कोशिश कर रहा था वह एक परिदृश्य है जहां हम बी को बी से पहले हल करने का इरादा रखते हैं, और ए वह वादा है जिसमें देरी होनी चाहिए। मतलब: मैं 'pushA' को अपने काम को पूरा करने के लिए, देरी सहित, और फिर-और-केवल-फिर' pushB' निष्पादित करना चाहता हूं। यहां एक अपडेटेड फीडल है, जो आपके इनपुट के साथ लागू हुआ है, जिसने मुझे जो खोजा था उस पर पहुंचने में मेरी सहायता की: https://jsfiddle.net/nam3cbaw/1/ – twip