एक बार सदस्यता बनाएँ


182

मुझे एक सदस्यता बनाने की आवश्यकता है Observableजिसे तुरंत पहली बार कॉल किए जाने पर निपटाया जाए।

क्या कुछ ऐसा है:

observable.subscribeOnce(func);

मेरा उपयोग मामला, मैं एक्सप्रेस मार्ग हैंडलर में एक सदस्यता बना रहा हूं और सदस्यता को प्रति अनुरोध कई बार कहा जा रहा है।

जवाबों:


319

आपकी आवश्यकता के बारे में 100% निश्चित नहीं है, लेकिन यदि आप केवल पहले मूल्य का निरीक्षण करना चाहते हैं, तो या तो उपयोग करें : first()याtake(1)

observable.first().subscribe(func);

ध्यान दें: .take(1)और .first()दोनों अपनी स्थिति पूरी होने पर स्वचालित रूप से सदस्यता समाप्त कर लेते हैं

आरएक्सजेएस 5.5+ से अपडेट करें

कोडर की टिप्पणी से ।

import { first } from 'rxjs/operators'

observable
  .pipe(first())
  .subscribe(func);

यहाँ पर क्यों


33
क्या सदस्यता के बाद स्वचालित रूप से सफाई हो जाती है?
बर्कले मार्टिनेज

50
हाँ यह करता है। जब उनकी स्थिति पूरी हो जाती है तो पहले दोनों को अनसब्सक्राइब कर लें।
ब्रैंडन

20
दस्तावेज़ीकरण यह क्यों नहीं कहता है कि यह स्वतः सदस्यता का निपटान करता है?
जेजिग

17
यह एक सामान्य RxJS नियम है कि जब एक अवलोकन योग्य धारा समाप्त हो जाती है तो सदस्यता का निपटान कर दिया जाता है। इसका मतलब है कि कोई भी ऑपरेटर जो एक धारा को "छोटा" करता है (या इसे एक अलग प्रकार की धारा में बदल देता है) स्रोत स्ट्रीम से उनके ऑपरेशन के पूरा होने पर सदस्यता समाप्त कर देगा। मुझे यकीन नहीं है कि कहाँ या अगर यह प्रलेखन में कहा गया है।
ब्रैंडन

37
अगर 2018 में कोई भी इसके लिए आ रहा है, तो आप वास्तव में चाहते हैं observable.pipe(first()).subscribe(func), जहां से firstआता है rxjs/operators
कोडर

32

RxJS के पास कुछ बेहतरीन दस्तावेज हैं जो मैंने कभी पूरे किए हैं। बलो लिंक का अनुसरण करने से आप ऑपरेटरों को अत्यधिक उपयोगी तालिका मानचित्रण मामलों का उपयोग करेंगे। उदाहरण के लिए, के अंतर्गत उपयोग के मामले "मैं पहली बार मूल्य ले जाना चाहते हैं" तीन ऑपरेटरों हैं: first, firstOrDefault, और sample

ध्यान दें, अगर कोई अवलोकन योग्य क्रम बिना किसी सूचना के पूरा होता है, तो firstऑपरेटर ग्राहकों को एक त्रुटि के साथ सूचित करता है जबकि firstOrDefaultऑपरेटर ग्राहकों को एक डिफ़ॉल्ट मूल्य प्रदान करता है।

ऑपरेटर केस लुकअप का उपयोग करते हैं


3

यदि आप केवल एक ऑब्जर्वेबल को एक बार कॉल करना चाहते हैं, तो इसका मतलब है कि आप इसके लिए स्ट्रीम का इंतजार नहीं करेंगे। तो toPromise()इसके बजाय का उपयोग subscribe()करना आपके मामले में पर्याप्त होगा क्योंकि toPromise()सदस्यता रद्द करने की आवश्यकता नहीं है।


बहुत ही दिलचस्प यह भी मतलब है कि हम यह कर सकते हैं बस जो इसे एक लाइनर बनाता हैawaitpromise
लुई Almeda

@ LouieAlmeda क्या आप हमें एक लाइनर का उदाहरण दे सकते हैं?
अदो रेन

हाय @AdoRen, मैंने आपके लिए यहां एक उत्तर में तकनीक को उजागर किया है, मुझे आशा है कि इससे मदद मिलती है।
लूई अल्मेडा

2

@ ब्रैंडन के उत्तर के पूरक के लिए , इसके आधार पर first()अपडेट करने के लिए उपयोग करना या पसंद करना भी आवश्यक है । उदाहरण के लिए (अप्राप्त):BehaviorSubjectObservable

var subject = new BehaviorSubject({1:'apple',2:'banana'});
var observable = subject.asObservable();

observable
  .pipe(
    first(), // <-- Ensures no stack overflow
    flatMap(function(obj) {
      obj[3] = 'pear';
      return of(obj);
    })
  )
  .subscribe(function(obj) {
    subject.next(obj);
  });

2

स्वच्छ और सुविधाजनक संस्करण

एम फूआट नौरोलू के अद्भुत जवाब को एक वादे के मुताबिक बदलने के अद्भुत जवाब पर विस्तार से, यहां इसका बहुत सुविधाजनक संस्करण है।

const value = await observable.toPromise();

console.log(value)

इसका सौंदर्य यह है कि हम उस मूल्य का उपयोग किसी अन्य नेस्टेड ब्लॉक को प्रस्तुत किए बिना एक सामान्य चर की तरह कर सकते हैं!

यह विशेष रूप से आसान है जब आपको कई वेधशालाओं से कई मान प्राप्त करने की आवश्यकता होती है। साफ़ सुथरा।

const content = await contentObservable.toPromise();
const isAuthenticated = await isAuthenticatedObservable.toPromise();

if(isAuthenticated){
   service.foo(content)
}

asyncयदि आप इस मार्ग से जाना चाहते हैं , तो निश्चित रूप से, आपको अपना कार्य करना होगा। .thenयदि आप नहीं चाहते कि आप वादे को पूरा करना चाहते हैं तो आप केवल वादा भी कर सकते हैं

मुझे यकीन नहीं है कि अगर इस दृष्टिकोण के साथ ट्रेडऑफ हैं, तो बेझिझक मुझे टिप्पणियों में बताएं ताकि हम जागरूक हों।

PS अगर आपको यह उत्तर पसंद आया है, तो M Fuat NUROULU के उत्तर को भी न भूलें। :)


0

मेरा भी ऐसा ही सवाल था।

नीचे अलग-अलग राज्य परिवर्तक से बाद में भी बुलाया गया था। जैसा कि मैं नहीं चाहता था।

function foo() {
    // this was called many times which was not needed
    observable.subscribe(func);
    changeObservableState("new value");
}

मैंने unsubscribe()नीचे के रूप में सदस्यता के बाद कोशिश करने का फैसला किया ।

function foo() {
    // this was called ONE TIME
    observable.subscribe(func).unsubscribe();
    changeObservableState("new value");
}

subscribe(func).unsubscribe();की तरह है subscribeOnce(func)

मुझे उम्मीद है कि आपने भी मदद की।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.