सब्जेक्ट बनाम बिहेवियरसॉबजेक्ट बनाम रिप्लेसेबजेक्ट इन एंगुलर


123

मैं उन 3 को समझने के लिए देख रहा हूँ:

विषय , व्यवहार विषय और रीप्ले विषय । मैं उनका उपयोग करना चाहता हूं और यह जानना चाहता हूं कि कब और क्यों, उनका उपयोग करने के क्या फायदे हैं और हालांकि मैंने प्रलेखन पढ़ा है, ट्यूटोरियल देखा है और Google को खोजा है मैं इसका कोई अर्थ निकालने में विफल रहा हूं।

तो उनका उद्देश्य क्या है? एक वास्तविक दुनिया के मामले की सबसे अधिक सराहना की जाएगी यह कोड भी नहीं है।

मैं केवल "a + b => c जिसे आप सदस्यता लेते हैं ....

धन्यवाद


1
पहले से ही अवलोकन के साथ व्यवहार विषय के साथ एक सवाल है; stackoverflow.com/questions/39494058/… और पुनरावृत्ति विषय पर प्रलेखन स्पष्ट है imo github.com/Reactive-Extensions/RxJS/blob/master/doc/api/…
Eko

इस उत्तर में Rxjs में विषयों की अपेक्षाकृत पूरी तरह से प्रस्तुति है , जो अच्छी तरह से peeksilet से उत्तर का पूरक है। इसमें समाप्ति के बाद व्यवहार के बारे में महत्वपूर्ण विवरण भी शामिल हैं, इसलिए एक नज़र रखना अच्छा है।
user3743222

जवाबों:


278

यह वास्तव में व्यवहार और शब्दार्थ के लिए नीचे आता है। के साथ

  • Subject- सब्सक्राइबर को केवल प्रकाशित मूल्य मिलेंगे जो सदस्यता के बाद उत्सर्जित किए गए थे । अपने आप से पूछें, क्या आप यही चाहते हैं? क्या सब्सक्राइबर को पिछले मूल्यों के बारे में कुछ भी जानने की आवश्यकता है? यदि नहीं, तो आप इसका उपयोग कर सकते हैं, अन्यथा दूसरों में से एक का चयन करें। उदाहरण के लिए, घटक-से-घटक संचार के साथ। मान लें कि आपके पास एक घटक है जो एक बटन क्लिक पर अन्य घटकों के लिए घटनाओं को प्रकाशित करता है। संवाद करने के लिए आप किसी विषय के साथ सेवा का उपयोग कर सकते हैं।

  • BehaviorSubject- अंतिम मान कैश किया गया है। एक ग्राहक को आरंभिक सदस्यता पर नवीनतम मूल्य मिलेगा। इस विषय का शब्दार्थ एक मूल्य का प्रतिनिधित्व करना है जो समय के साथ बदलता है। उदाहरण के लिए एक लॉग इन उपयोगकर्ता। प्रारंभिक उपयोगकर्ता एक अनाम उपयोगकर्ता हो सकता है। लेकिन एक बार जब कोई उपयोगकर्ता लॉग इन करता है, तो नया मान प्रमाणित उपयोगकर्ता स्थिति है।

    BehaviorSubjectएक प्रारंभिक मूल्य के साथ आरंभ नहीं हो जाता। वरीयता को कोडित करने के लिए यह कभी-कभी महत्वपूर्ण होता है। उदाहरण के लिए कहें कि आप इसे एक के साथ शुरू करते हैं null। फिर आपकी सदस्यता में, आपको एक शून्य जांच करने की आवश्यकता है। शायद ठीक है, या शायद गुस्सा आ रहा है।

  • ReplaySubject- यह उत्सर्जन की एक निश्चित संख्या तक कैश कर सकता है। किसी भी ग्राहक को सदस्यता पर सभी कैश्ड मान मिलेंगे। आपको इस व्यवहार की आवश्यकता कब होगी? ईमानदारी से, मुझे इस तरह के व्यवहार की कोई आवश्यकता नहीं है, सिवाय निम्नलिखित मामले के:

    यदि आप ReplaySubjectएक बफर आकार के साथ आरंभ करते हैं 1, तो यह वास्तव में एक की तरह व्यवहार करता है BehaviorSubject। अंतिम मान हमेशा कैश किया जाता है, इसलिए यह समय के साथ मूल्य बदलने की तरह काम करता है। इसके साथ, ए के साथ इनिशियलाइज्ड nullके मामले में चेक की जरूरत नहीं BehaviorSubjectहै null। इस उदाहरण में, पहले प्रकाशन तक ग्राहक का कोई मूल्य कभी भी उत्सर्जित नहीं किया जाता है।

तो यह वास्तव में उस व्यवहार के लिए नीचे आता है जिसकी आप अपेक्षा कर रहे हैं (जिसके लिए किसी का उपयोग करना है)। अधिकांश समय आप शायद इसका उपयोग करना चाहेंगे BehaviorSubjectक्योंकि आप वास्तव में जो प्रतिनिधित्व करना चाहते हैं, वह है "समय के साथ मूल्य" शब्दार्थ। लेकिन मैं व्यक्तिगत रूप से ReplaySubjectआरंभिक के प्रतिस्थापन के साथ कुछ भी गलत नहीं देखता हूं 1

क्या आप चाहते हैं से बचने के वेनिला उपयोग कर रहा है Subjectजब आप वास्तव में क्या जरूरत कुछ कैशिंग व्यवहार है। उदाहरण के लिए आप एक राउटिंग गार्ड या एक संकल्प लिख रहे हैं। आप उस गार्ड में कुछ डेटा लाते हैं और इसे एक सेवा में सेट करते हैं Subject। फिर रूट किए गए घटक में आप उस विषय को प्राप्त करने के लिए सेवा विषय की सदस्यता लेते हैं जो कि गार्ड में उत्सर्जित किया गया था। उफ़। मूल्य कहां है? यह पहले से ही उत्सर्जित था, डीयूएच। एक "कैशिंग" विषय का उपयोग करें!

यह सभी देखें:


1
मतभेदों को समझने के लिए यह छोटा और आसान है। जब मूल्य सेवा में बदलता है और घटक भी बदलते हैं कि मूल्य दिखाया जाता है, तो व्यवहार समाधान या रिप्ले विषय विषय समाधान है।
सैय्यफ फ़ारूक

1
धन्यवाद! ReplaySubject1 के एक बफ़र आकार के साथ वास्तव में मुझे क्या चाहिए था। मेरे पास एक रूट गार्ड था जिसे मूल्य की आवश्यकता थी, लेकिन पहले उत्सर्जन की प्रतीक्षा करने की आवश्यकता थी। इसलिए ए BehaviorSubjectइसे नहीं काट रहा था, क्योंकि मैं एक प्रारंभिक मूल्य नहीं चाहता था ( nullया तो काम नहीं करेगा क्योंकि मैं इसे एक राज्य को इंगित करने के लिए उपयोग कर रहा था)
menehune23

1
@ menehune23 मुझे एक Angular resolveguard class के लिए ReplaySubject की भी आवश्यकता थी । मेरी डेटा सेवा अतुल्यकालिक, या सिंक्रोनस हो सकती है (यदि डेटा पहले ही पुनर्प्राप्त कर लिया गया था)। यदि यह सिंक्रोनस था, तो फंक्शन resolveवापस आने से पहले Subject.next () को निकाल दिया जा रहा था और इसे Angly द्वारा आंतरिक रूप से सब्सक्राइब किया गया था। BehaviourSubject संभवत: काम करेगा, लेकिन मुझे आसानी से कॉल करना होगा complete()और nullप्रारंभिक मूल्य के लिए चेक भी जोड़ना होगा । क्या काम किया गया थाReplaySubject<DataType>(1)resolveSubject.asObservable().take(1).map(....)
Drenai

1
मैं 1 के बफ़र आकार के साथ एक ReplaySubject का उपयोग कर रहा हूं, लेकिन किसी कारण से जब मैं ऑब्जर्वेबल के साथ एक ऑब्जर्वेबल प्राप्त करता हूं, तो इससे पहले कि मैं कभी भी अपने ReplaySubject पर कॉल करूं, ग्राहकों .asObservable()का मान भेजूं। मुझे लगा कि व्यवहार के विपरीत एक प्रारंभिक मूल्य होना चाहिए था? nullnext()
काइल वी।

2
मुझे लगता है कि रीप्ले विषय के लिए आपके द्वारा उल्लेखित एक बहुत ही आसान उदाहरण "चैटरूम" या गेम लॉबी परिदृश्य के लिए होगा जहां आप नए जॉइनर्स को अंतिम 10 संदेश देखना चाहते हैं।
जेम्स

16

विभिन्न अवलोकन प्रकारों का एक आसान सारांश, गैर सहज ज्ञान युक्त नामकरण मुझे पता है

  • Subject - सब्सक्राइबर को केवल प्रकाशित मूल्य ही मिलेंगे, उसके बाद-सब्सक्रिप्शन बना दिया जाता है।
  • BehaviorSubject - नए ग्राहकों को सदस्यता पर तुरंत अंतिम प्रकाशित मूल्य या प्रारंभिक मूल्य मिलता है।
  • ReplaySubject - नए ग्राहकों को सदस्यता के तुरंत पहले सभी प्रकाशित मूल्य मिलते हैं

1-एन प्रकाशित मान? तो अगर वहाँ 2 प्रकाशित मूल्यों थे एक ReplaySubject -1 प्रकाशित मूल्यों का उत्पादन होगा ???
जेसन चेंग

@JasonCheng नहीं यह सदस्यता पर सभी पहले प्रकाशित मूल्यों को फिर से प्राप्त करता है, उत्तर अपडेट करें :)
रिकी बॉयस

11
  1. विषय : सदस्यता लेने पर हमेशा वह डेटा मिलता है जिसे सदस्यता के बाद धकेला जाता है अर्थात पिछले पुश किए गए मान प्राप्त नहीं होते हैं
const mySubject = new Rx.Subject();

mySubject.next(1);

const subscription1 = mySubject.subscribe(x => {
  console.log('From subscription 1:', x);
});

mySubject.next(2);

const subscription2 = mySubject.subscribe(x => {
  console.log('From subscription 2:', x);
});

mySubject.next(3);

subscription1.unsubscribe();

mySubject.next(4);

इस उदाहरण के साथ, यहाँ वह परिणाम है जो कंसोल में मुद्रित होगा:

From subscription 1: 2
From subscription 1: 3
From subscription 2: 3
From subscription 2: 4

ध्यान दें कि देरी से आने वाली सदस्यताएँ कुछ ऐसे डेटा से गायब हैं जिन्हें विषय में धकेला गया है।

  1. रीप्ले विषय : पिछले मानों की एक बफ़र रखने में मदद कर सकते हैं जो नए सदस्यता के लिए उत्सर्जित होंगे।

यहां उन विषयों को फिर से उपयोग करने के लिए उदाहरण दिया गया है, जहां buffer of 2 previous valuesनए सदस्यता पर रखे गए और उत्सर्जित किए जाते हैं:

const mySubject = new Rx.ReplaySubject(2);

mySubject.next(1);
mySubject.next(2);
mySubject.next(3);
mySubject.next(4);

mySubject.subscribe(x => {
  console.log('From 1st sub:', x);
});

mySubject.next(5);

mySubject.subscribe(x => {
  console.log('From 2nd sub:', x);
});

यहाँ वह है जो हमें दिलासा देता है:

From 1st sub: 3
From 1st sub: 4
From 1st sub: 5
From 2nd sub: 4
From 2nd sub: 5
  1. व्यवहार विषय : फिर से खेलना विषयों के समान हैं, लेकिन केवल अंतिम उत्सर्जित मूल्य, या डिफ़ॉल्ट मान फिर से उत्सर्जित किया जाएगा यदि कोई मूल्य पहले उत्सर्जित नहीं किया गया है:
const mySubject = new Rx.BehaviorSubject('Hey now!');

mySubject.subscribe(x => {
  console.log('From 1st sub:', x);
});

mySubject.next(5);

mySubject.subscribe(x => {
  console.log('From 2nd sub:', x);
});

और परिणाम:

From 1st sub: Hey now!
From 1st sub: 5
From 2nd sub: 5

संदर्भ: https://alligator.io/rxjs/subjects/


4

प्रेषक: रान्डल कौटनिक पुस्तक "आरएक्सजेएस के साथ प्रतिक्रियाशील वेबसाइटें बनाएँ।" :

एक विषय एक वस्तु है जो एक टर्बोचार्ज्ड अवलोकन योग्य है। इसके मूल में, एक विषय एक नियमित रूप से देखने योग्य की तरह काम करता है, लेकिन प्रत्येक सदस्यता एक ही स्रोत में आदी है। विषय भी पर्यवेक्षक हैं और उनके पास अगले, त्रुटि, और सभी ग्राहकों को एक साथ डेटा भेजने के तरीके हैं। क्योंकि विषय पर्यवेक्षक हैं, उन्हें सीधे सदस्यता कॉल में पारित किया जा सकता है, और मूल अवलोकन से सभी घटनाओं को विषय के माध्यम से अपने ग्राहकों को भेजा जाएगा।

हम इतिहास को ट्रैक करने के लिए ReplaySubject का उपयोग कर सकते हैं । एक ReplaySubject पिछले एन घटनाओं को रिकॉर्ड करता है और उन्हें हर नए ग्राहक को वापस देता है। चैट एप्लिकेशन में उदाहरण के लिए। हम इसका उपयोग पिछले चैट इतिहास के रिकॉर्ड को ट्रैक करने के लिए कर सकते हैं।

एक BehaviorSubject ReplaySubject का सरलीकृत संस्करण है । ReplaySubject संग्रहीत की घटनाओं की एक मनमाना संख्या, BehaviorSubject केवल नवीनतम घटना का मूल्य रिकॉर्ड करता है। जब भी BehaviorSubject एक नई सदस्यता रिकॉर्ड करता है, तो यह ग्राहक को नवीनतम मान और साथ ही पास किए गए किसी भी नए मान का उत्सर्जन करता है। BehaviorSubject राज्य की एकल इकाइयों के साथ काम करते समय उपयोगी होता है, जैसे कि विकल्प विकल्प।


1

अधिकांश उत्कीर्ण उत्तर स्पष्ट रूप से गलत दावा है कि:

"यदि आप ReplaySubject1 के बफर आकार के साथ आरंभ करते हैं , तो यह वास्तव में एक की तरह व्यवहार करता हैBehaviorSubject " की


यह पूरी तरह सच नहीं है; उन दो के बीच अंतर पर इस महान ब्लॉग पोस्ट की जाँच करें । उदाहरण के लिए यदि आप एक पूर्ण सदस्यता लेते हैं BehaviorSubject, तो आपको अंतिम मूल्य नहीं मिलेगा, लेकिन ए के लिएReplaySubject(1) आपके लिए अंतिम मूल्य प्राप्त होगा।

यह महत्वपूर्ण अंतर है जिसे अनदेखा नहीं किया जाना चाहिए:

const behavior = new BehaviorSubject(null);
const replay = new ReplaySubject(1);

behavior.skip(1).subscribe(v => console.log('BehaviorSubject:', v));
replay.subscribe(v => console.log('ReplaySubject:', v));

behavior.next(1);
behavior.next(2);
behavior.complete();
behavior.subscribe(v => console.log('Late B subscriber:', v));

replay.next(1);
replay.next(2);
replay.complete();
replay.subscribe(v => console.log('Late R subscriber:', v));

इस कोड का उदाहरण यहां देखें जो विषय पर एक और महान ब्लॉग पोस्ट से आता है ।


0
     // ***********Subject  concept ***********
    let subject = new Subject<string>();


    subject.next("Eureka");
    subject.subscribe((data) => {
      console.log("Subscriber 1 got data >>>>> "+ data);
    });
    subject.subscribe((data) => {
      console.log("Subscriber 2 got data >>>>> "+ data);
    });

       // ********behaviour subject*********
    // Behavior subjects need a first value
let subject1 = new BehaviorSubject<string>("First value");


subject1.asObservable().subscribe((data) => {
  console.log("First subscriber got data behaviour subject>>>>> "+ data);
});
subject1.next("Second value")
  • विषय - सब्सक्राइबर को केवल प्रकाशित मूल्य मिलेंगे, उसके बाद सदस्यता दी जाएगी।
  • व्यवहार-विषय - नए ग्राहकों को सदस्यता पर तुरंत अंतिम प्रकाशित मूल्य या प्रारंभिक मूल्य मिलता है।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.