2017-07-12 26 views
9

का इंतजार नहीं करता है मैं टाइपस्क्रिप्ट के साथ एक कोणीय 4 ऐप बना रहा हूं।कोणीय 4 सेटटाइमआउट

मेरे पास एक ऐसा फ़ंक्शन है जिसे निर्दिष्ट स्टॉपंडिशन तक हर 10 सेकंड में निष्पादित करने की आवश्यकता होती है। मैंने सेटटाइमआउट का उपयोग करके कुछ टेस्टकोड के साथ एक लूप बनाया है यह देखने के लिए कि यह काम करेगा या नहीं।

मेरे Testcode:

public run() { 
    let i = 0; 
    while (i < 4) { 
     setTimeout(this.timer,3000); 
     i++; 
    } 
} 

public timer(){ 
    console.log("done") 
} 

हालांकि इस 3 सेकंड के लिए प्रतीक्षा करने के लिए लगता है, या ब्राउज़र बस धीमी गति से ... है और फिर इसे 4 बार किया प्रिंट करता है। तो कोड काम नहीं कर रहा है। क्या मैं यह गलत कर रहा हूं या इस तरह की चीजों को करने के लिए अन्य संभावनाएं हैं?

उत्तर

15

जब से तुम कोणीय उपयोग कर रहे हैं तो आप शायद takeWhile का उपयोग कर एक बहुत सरल तरीके से ऐसा कर सकते हैं:

Observable.interval(10000) 
    .takeWhile(() => !stopCondition) 
    .subscribe(i => { 
     // This will be called every 10 seconds until `stopCondition` flag is set to true 
    }) 
+0

जब मैं इसे आज़माता हूं तो मुझे एक त्रुटि मिलती है: त्रुटि प्रकार त्रुटि: __WEBPACK_IMPORTED_MODULE_3_rxjs_Observable __। Observable.interval एक फ़ंक्शन नहीं है – fangio

+0

यह हास्यास्पद है कि मैंने आरएसएसजे/पर्यवेक्षण से {पर्यवेक्षण योग्य} आयात किया, जो काम नहीं किया ... उत्तर के लिए धन्यवाद :) – fangio

+5

@fangio कभी भी "rxjs" से आयात नहीं करता है। यही कारण है कि सभी प्रत्यक्ष स्थिर तरीकों और ऑपरेटरों, जो आपके आवेदन बंडल तरह से बड़ा होना चाहिए उस से कर देगा आयात करेगा। आपके पास आयात का उपयोग करें, और 'आयात' आरएक्सजे/जोड़ें/अवलोकन/अंतराल जोड़ें; आयात 'rxjs/जोड़/ऑपरेटर/takeWhile''; '। यही कारण है कि केवल तरीकों और ऑपरेटरों है कि आप वास्तव में उपयोग आयात करेगा। –

0

यह वास्तव में async विधि का उपयोग करने का तरीका नहीं है। while लूप सिर्फ एक बार में 4 बार जाता है, और 4 टाइमर शुरू करता है। जो एक साथ आउटपुट के साथ-साथ 3 सेकंड में भी आउटपुट करेगा। आप फिर भी टाइपप्रति से await और async कार्यक्षमता का लाभ उठाने कर सकते हैं:

public stopCondition: boolean = false; 

public async run(): void { 
    while (!this.stopCondition) { 
     await new Promise<void>(resolve => { 
      setTimeout(resolve, 10000); 
     }); 
     this.execute(); 
    } 
    console.log('done'); 
} 

public execute(): void { 
    if ('whatever should trigger your stop condition') { 
     this.stopCondition = true; 
    } 
} 

यह हर 10 सेकंड के बाद execute विधि चलेगा, जब तक stopCondition === false के रूप में के लिए। जब stopCondition === true यह done आउटपुट करेगा।

0

हां, यह सही व्यवहार है। आपके पास सिंक्रोनस लूप है जिसने 4 देरी की कार्रवाइयां बनाई हैं और इस लूप को समाप्त कर दिया है। यह कुछ मिलीसेकंड में होता है। इसलिए सभी 4 देरी वाली कार्रवाइयां एक ही समय में 3 सेकंड में शुरू होने के लिए पंजीकृत हैं।

तो 3 सेकंड में आपको इस देरी हुई कार्रवाइयों से सभी 4 प्रतिक्रियाएं मिलेंगी।

यदि आप परिणाम निष्पादन करना चाहते हैं (पहले 3 सेकंड के बाद, फिर पहले के बाद दूसरा) इसके लिए वादे का उपयोग करने पर विचार करें और पिछले पूर्ण होने के बाद 3 सेकंड देरी के साथ नए वादे को कॉल करें।

fisrtPromise 
    .then(secondPromise) 
    .then(thirdPromise); 

https://developer.mozilla.org/uk/docs/Web/JavaScript/Reference/Global_Objects/Promise

2

हाँ, आप गलत कर रहे हैं: आप एक पाश एक पंक्ति में 4 बार कह 3 सेकंड बाद timer() निष्पादित करने के लिए, अब से की है।

आप क्या चाहते करने के लिए, आप अगले टाइमर हर बार timer() कहा जाता है को पुनर्निर्धारित करने के लिए होगा या, और अधिक बस, setInterval() उपयोग करने के लिए:

let count = 0; 
const interval = window.setInterval(() => { 
    this.timer(); 
    count++; 
    if (count >= 4) { 
     window.clearInterval(interval); 
    } 
}, 3000); 

ध्यान दें कि, जब से तुम कोणीय उपयोग कर रहे हैं, observables का उपयोग कर muuuch आसान होगा:

Observable.interval(3000).take(4).subscribe(() => this.timer()); 
+0

बस अपने स्वयं के संदर्भ के लिए आवश्यक कार्यक्षमता प्राप्त कर सकते हैं, यदि आप किसी निश्चित स्थिति को पूरा कर चुके हैं तो आप 'अवलोकन योग्य' अंतराल को कैसे रोक सकते हैं।उदाहरण के लिए जब एक वर्ग क्षेत्र बन जाता है के लिए 'TRUE' – PierreDuc

+0

' takeWhile (() =>! this.someField) ' –

+0

लवली! ऐसा लगता है कि वे सब कुछ के लिए :) – PierreDuc

0

चूंकि आप लूप के दौरान सेटटाइमआउट को कॉल कर रहे हैं और कथन के असीमित निष्पादन के कारण यह अगले पुनरावृत्ति पर जाने से पहले टाइमर फ़ंक्शन निष्पादित करने की प्रतीक्षा नहीं करेगा। आप नीचे दिए गए कोड

public run() { 
    var i = 0; 
    var interval = setInterval(() => { 
     if (++i === 4) {     
      clearInterval(interval); 
     } 
     else { 
      this.timer(); 
     } 
    }, 3000); 

} 

public timer() { 
    console.log("done") 
}