web-dev-qa-db-ja.com

AngularのSubject vs BehaviorSubject vs ReplaySubject

私はそれらを理解しようとしています:

サブジェクト動作サブジェクトおよびリプレイサブジェクト。私はそれらを使用して、いつ、なぜ、それらを使用することの利点を知りたいと思います。ドキュメントを読んで、チュートリアルを見て、グーグルを検索しましたが、私はこれを理解できませんでした。

それで、彼らの目的は何ですか?現実世界の場合は、コーディングすらする必要はありません。

「a + b => cあなたが購読している...」だけでなく、わかりやすい説明をお勧めします。

ありがとうございました

68
user6015054

それは実際に動作とセマンティクスに帰着します。とともに

  • Subject-サブスクライバーは、サブスクリプション後に発行されたパブリッシュされた値のみを取得します。自問してください、それはあなたが望むものですか?加入者は以前の値について何か知る必要がありますか?そうでない場合は、これを使用できます。そうでない場合は、他のいずれかを選択します。たとえば、コンポーネント間の通信。ボタンのクリックで他のコンポーネントのイベントを発行するコンポーネントがあるとします。あなたは通信するためにサブジェクトでサービスを使用できます。

  • BehaviorSubject-最後の値がキャッシュされます。加入者は、最初の加入時に最新の値を取得します。このサブジェクトのセマンティクスは、時間とともに変化する値を表すことです。たとえば、ログインしているユーザー。初期ユーザーは匿名ユーザーである場合があります。ただし、ユーザーがログインすると、新しい値は認証されたユーザーの状態になります。

    BehaviorSubjectは初期値で初期化されます。これは、コーディング設定にとって重要な場合があります。たとえば、nullで初期化するとします。次に、サブスクリプションで、nullチェックを行う必要があります。多分大丈夫、または多分迷惑です。

  • ReplaySubject-指定された排出量までキャッシュできます。購読者は、購読時にすべてのキャッシュされた値を取得します。この動作が必要になるのはいつですか?正直なところ、次の場合を除き、このような動作は必要ありませんでした。

    ReplaySubject1のバッファーサイズで初期化すると、実際にはbehaviorsBehaviorSubjectと同じように動作します。最後の値は常にキャッシュされるため、時間とともに変化する値のように機能します。これにより、nullで初期化されたBehaviorSubjectの場合のように、nullチェックは必要ありません。最初の発行までサブスクライバーに値が発行されないためです。

したがって、どちらを使用するかについては、実際に期待する動作になります。たいていの場合、おそらくBehaviorSubjectを使用したいと思うでしょう。なぜなら、あなたが本当に表現したいのは、その「経時的な値」セマンティックだからです。しかし、私は個人的に1で初期化されたReplaySubjectの置換に何の問題も見ていません。

avoidにしたいのは、実際に必要なのがキャッシュ動作であるときにVanilla Subjectを使用することです。たとえば、ルーティングガードまたは解決を書いているとします。そのガードでいくつかのデータをフェッチし、それをサービスSubjectに設定します。次に、ルーティングされたコンポーネントで、サービスサブジェクトをサブスクライブして、ガードで発行された値を取得しようとします。おっとっと。値はどこですか?すでに放出されました、DUH。 「キャッシング」サブジェクトを使用してください!

こちらもご覧ください:

171
Paul Samsotha

さまざまな観察可能なタイプの便利な要約非直感的な命名、私は笑を知っています

  • Subject-サブスクライバーは、サブスクリプションが作成された後にのみ、公開された値を取得します。
  • BehaviorSubject-新しいサブスクライバーは、サブスクリプション直後に最後に公開された値OR初期値を取得します。
  • ReplaySubject-新しいサブスクライバーは、サブスクリプション直後に(最後に発行された場合のみ)最後の1-n発行された値を取得します。
4
Ricky Boyce

From:Randall Koutnikの本「RxJSを使用したリアクティブWebサイトの構築」:

Subjectは、ターボチャージされたオブザーバブルであるオブジェクトです。コアでは、Subjectは通常のオブザーバブルによく似ていますが、各サブスクリプションは同じソースにフックされます。 Subjectsもオブザーバーであり、すべてのサブスクライバーに一度にデータを送信するためのnext、error、およびdoneメソッドがあります。 subjectsはオブザーバーであるため、サブスクライブ呼び出しに直接渡すことができ、元のオブザーバブルからのすべてのイベントはサブジェクトを介してサブスクライバーに送信されます。

ReplaySubjectを使用して履歴を追跡できます。 ReplaySubjectは、最後のn個のイベントを記録し、それらをすべての新しいサブスクライバーに戻します。たとえば、チャットアプリケーション。以前のチャット履歴の記録を追跡するために使用できます。

BehaviorSubjectは、ReplaySubjectの簡易バージョンです。 ReplaySubjectは任意の数のイベントを保存し、BehaviorSubjectは最新のイベントの値。 BehaviorSubjectが新しいサブスクリプションを記録するたびに、最新の値と、渡された新しい値がサブスクライバーに発行されます。BehaviorSubjectは、構成オプションなどの単一の状態ユニットを扱う場合に便利です。

2
H S Progr
     // ***********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")
  • 件名-サブスクライバーは、サブスクリプションが行われた後にのみ公開された値を取得します。
  • BehaviorSubject-新しいサブスクライバーは、サブスクリプションの直後に最後に公開された値OR初期値を取得します。
0
user8199162
  1. Subject:サブスクリプションでは、サブスクリプションの後にプッシュされたデータを常に取得します。つまり、以前にプッシュされた値は受信されません
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/

0
Varun Sukheja