Konu vs Davranış Konu - Açısal Olarak Yeniden Oynatma Konu


124

Bu 3'ü anlamaya çalışıyordum:

Konu , Davranış konusu ve Tekrar konusu . Bunları kullanmak istiyorum ve ne zaman ve neden kullanmanın faydalarının neler olduğunu bilmek istiyorum ve belgeleri okudum, öğreticileri izledim ve google'da arama yapsam da bunu anlamayı başaramadım.

Öyleyse amaçları ne? Gerçek dünyadaki bir vakanın kodlanması bile gerekmediği çok takdir edilecektir.

Açık bir açıklamayı sadece "a + b => c abone olduğunuz ...." değil tercih ederim.

teşekkür ederim


1
Gözlenebilir olan davranış öznesi ile ilgili bir soru zaten var; stackoverflow.com/questions/39494058/… ve yeniden oynatma konusundaki belgeler açıktır imo github.com/Reactive-Extensions/RxJS/blob/master/doc/api/…
eko

Bu cevapta , peeksilet'in cevabını güzel bir şekilde tamamlayan Rxjs'deki konuların nispeten kapsamlı bir sunumu var . Bu, sonlandırmadan sonraki davranışla ilgili önemli ayrıntıları da içerir, bu nedenle bir göz atmak iyidir.
user3743222

Yanıtlar:


278

Gerçekten davranış ve anlambilimle ilgilidir. Birlikte

  • Subject- bir abone, yalnızca abonelikten sonra yayınlanan yayınlanmış değerleri alır . Kendine sor, istediğin bu mu? Abonenin önceki değerler hakkında herhangi bir şey bilmesi gerekiyor mu? Değilse, bunu kullanabilirsin, yoksa diğerlerinden birini seç. Örneğin, bileşenden bileşene iletişim ile. Bir düğme tıklamasıyla diğer bileşenler için etkinlikler yayınlayan bir bileşeniniz olduğunu varsayalım. İletişim kurmak için bir konuya sahip bir hizmeti kullanabilirsiniz.

  • BehaviorSubject- son değer önbelleğe alınır. Bir abone, ilk abonelikte en son değeri alacaktır. Bu konu için anlambilim, zamanla değişen bir değeri temsil etmektir. Örneğin oturum açmış bir kullanıcı. İlk kullanıcı anonim bir kullanıcı olabilir. Ancak bir kullanıcı oturum açtığında, yeni değer kimliği doğrulanmış kullanıcı durumudur.

    BehaviorSubjectBir başlangıç değeri ile başlatılır. Bu bazen kodlama tercihi için önemlidir. Örneğin, onu bir null. Ardından aboneliğinizde boş bir kontrol yapmanız gerekir. Belki tamam ya da can sıkıcı olabilir.

  • ReplaySubject- belirli sayıda emisyonu önbelleğe alabilir. Herhangi bir abone, abonelik sırasında önbelleğe alınan tüm değerleri alacaktır. Bu davranışa ne zaman ihtiyaç duyarsınız? Dürüst olmak gerekirse, aşağıdaki durum dışında böyle bir davranışa ihtiyacım olmadı:

    Eğer bir başlatırsanız ReplaySubjectbir tampon boyutu ile 1, o zaman aslında davranır sadece gibi BehaviorSubject. Son değer her zaman önbelleğe alınır, bu nedenle zaman içinde değişen bir değer gibi davranır. Bununla birlikte, a ile ilklendirilmiş nulldurumdaki gibi bir kontrole gerek yoktur . Bu durumda aboneye ilk yayına kadar hiçbir değer gönderilmez.BehaviorSubjectnull

Yani gerçekten beklediğiniz davranışa (hangisini kullanacağınızla ilgili) gelir. Çoğu zaman muhtemelen a kullanmak isteyeceksiniz BehaviorSubjectçünkü gerçekten temsil etmek istediğiniz şey "zaman içindeki değer" anlambilimidir. Ama şahsen ReplaySubjectbaşlatılan ile ikame edilmesinde yanlış bir şey görmüyorum 1.

Kaçınmak istediğiniz Subjectşey, gerçekten ihtiyacınız olan şey önbelleğe alma davranışı olduğunda vanilyayı kullanmaktır . Örneğin, bir yönlendirme koruyucusu veya bir çözüm yazıyorsunuz. Bu korumadan bazı veriler alırsınız ve bir hizmete ayarlarsınız Subject. Daha sonra yönlendirilmiş bileşende, korumada yayılan değeri almaya çalışmak için hizmet konusuna abone olursunuz. Cepten. Değer nerede? Zaten yayınlandı, DUH. Bir "önbelleğe alma" konusu kullanın!

Ayrıca bakınız:


1
Bu kısa ve farklılıkları anlamak kolaydır. Hizmette değer değiştiğinde ve bileşenler de değerin gösterilmesini değiştirdiğinde, Çözüm Davranış Özneleri veya Yeniden Oynatma Konusu olur.
Saiyaff Farouk

1
Teşekkür ederim! ReplaySubject1 tampon boyutuyla tam olarak ihtiyacım olan şeydi. Değere ihtiyaç duyan ancak ilk emisyonu beklemem gereken bir rota korumam vardı. Yani a BehaviorSubjectonu null
kesmiyordu

1
@ menehune23 Ayrıca bir Angular resolvekoruma sınıfı için ReplaySubject'e ihtiyacım vardı . Veri servisim eşzamansız veya eşzamanlı olabilir (veriler önceden alınmışsa). Eşzamanlıysa, Subject.next () resolveişlevi geri dönmeden ve Angular tarafından dahili olarak abone olmadan önce çalıştırılıyordu . BehaviourSubject muhtemelen işe yarayabilirdi, ancak açık bir şekilde çağırmam complete()ve nullilk değer için kontroller eklemem gerekir . ReplaySubject<DataType>(1)resolveSubject.asObservable().take(1).map(....)
İşe yarayan

1
Arabellek boyutu 1 olan bir ReplaySubject kullanıyorum, ancak bazı nedenlerden dolayı bir Observable ile bir Observable aldığımda, ReplaySubject'imi aramadan önce abonelere .asObservable()bir değer gönderiyorum. BehaviorSubject'ten farklı olarak bir başlangıç ​​değerine sahip olmaması gerektiğini düşündüm. nullnext()
Kyle V.

2
Yeniden oynatma konusu için bahsedebileceğiniz oldukça kolay bir örnek, yeni katılanların son 10 mesajı görmesini istediğiniz bir "sohbet odası" veya oyun lobisi senaryosu olabilir.
James

16

Farklı gözlemlenebilir türlerin kullanışlı bir özeti, sezgisel olmayan adlandırma lol biliyorum .

  • Subject - Bir abone, abonelik yapıldıktan sonra sadece yayınlanan değerleri alacaktır.
  • BehaviorSubject - Yeni aboneler, abonelikten hemen sonra yayınlanan son değeri VEYA başlangıç ​​değerini alır.
  • ReplaySubject - Yeni aboneler, abonelikten hemen sonra önceden yayınlanan tüm değerleri alır

1-n yayınlanmış değerler? Yani 2 yayınlanmış değer olsaydı, bir ReplaySubject -1 yayınlanmış değer üretirdi ???
Jason Cheng

@JasonCheng hayır, abonelik üzerine daha önce yayınlanan tüm değerleri alır, yanıtı güncelle :)
Ricky Boyce

11
  1. Konu : Abone olurken, abonelikten sonra itilen verileri her zaman alır, yani önceki itilen değerler alınmaz .
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);

Bu örnekle, konsolda yazdırılacak sonuç şu şekildedir:

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

Geç gelen aboneliklerin konuya aktarılan bazı verilerin nasıl eksik olduğuna dikkat edin.

  1. Tekrar oynatma konuları : yeni aboneliklere gönderilecek önceki değerlerin bir arabelleğini tutarak yardımcı olabilir .

Aşağıda, a'nın buffer of 2 previous valuestutulduğu ve yeni aboneliklerde yayınlandığı yeniden oynatma konuları için bir kullanım örneği verilmiştir :

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);
});

Bunun bize konsolda verdiği şeyler:

From 1st sub: 3
From 1st sub: 4
From 1st sub: 5
From 2nd sub: 4
From 2nd sub: 5
  1. Davranış konuları : tekrar konularına benzer, ancak yalnızca son yayınlanan değeri veya daha önce herhangi bir değer gönderilmemişse varsayılan bir değeri yeniden yayar:
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);
});

Ve sonuç:

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

Referans: https://alligator.io/rxjs/subjects/


4

Gönderen: Randall Koutnik "RxJS ile Reaktif Web Siteleri Oluşturun" kitabı. :

Bir Konu Bir gözlemlenebilir turboşarjlı var bir nesnedir. Özünde, bir Özne normal bir gözlemlenebilir gibi davranır, ancak her abonelik aynı kaynağa bağlanır. Denekler aynı zamanda gözlemcilerdir ve tüm abonelere aynı anda veri göndermek için sonraki, hata ve yapılan yöntemlere sahiptir. Çünkü denekler gözlemciler, onlar bir abone çağrı doğrudan geçirilebilir ve orijinal gözlemlenebilir gelen tüm olaylar Abonelerine konu olan gönderilecektir.

Geçmişi takip etmek için ReplaySubject'i kullanabiliriz . Bir ReplaySubject onları her yeni aboneye geri son n olayları ve Palys kaydeder. Örneğin sohbet uygulamasında. Önceki sohbet geçmişinin kaydını takip etmek için kullanabiliriz.

Bir BehaviorSubject basitleştirilmiş sürümüdür ReplaySubject . ReplaySubject olayların rastgele sayıda saklanan, BehaviorSubject sadece son olayın değerini kaydeder. Bir BehaviorSubject yeni bir abonelik kaydettiğinde, aboneye en son değeri ve aktarılan tüm yeni değerleri gönderir . BehaviorSubject , yapılandırma seçenekleri gibi tek durum birimleriyle uğraşırken kullanışlıdır.


1

Çoğu olumlu oy verilen cevap, şu iddiayı ileri sürmekle açıkça yanlıştır:

"Eğer bir başlatırsanız ReplaySubject1 bir tampon boyutu ile, o zaman aslında sadece bir gibi davranır BehaviorSubject"


Bu tamamen doğru değil; bu ikisi arasındaki farklar hakkındaki bu harika blog gönderisine göz atın . Örneğin, bir tamamlanmışa abone BehaviorSubjectolursanız, son değeri almayacaksınız, ancak bir için ReplaySubject(1)son değeri alacaksınız.

Bu, gözden kaçırılmaması gereken önemli bir farktır:

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));

Konuyla ilgili başka bir harika blog gönderisinden gelen bu kod örneğini buradan kontrol edin .


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")
  • Konu - Bir abone, yalnızca abonelik yapıldıktan sonra yayınlanan değerleri alacaktır.
  • BehaviorSubject - Yeni aboneler, abonelikten hemen sonra yayınlanan son değeri VEYA başlangıç ​​değerini alır.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.