見出し画像

RxJS_SubscriptionとSubjectの違い #389

綴りが似ていて混同しやすい、SubscriptionとSubjectという2つのオブジェクトについて整理します。

Subscritptionとは

これはObservableからのデータストリームを監視(つまり"subscribe")している間、その関連性を維持するオブジェクトです。

これはつまり、以前の記事でも触れたsubscribeメソッドでObservableを購読した際、この購読そのものがSubscriptionオブジェクトとして返されるということです。

購読そのものがオブジェクトになっているので、購読を後でunsubscribe(解除)できます。これはメモリリークを防いだり、不要になったときにリソースをクリーンアップする重要な役割を果たします。

public subscription = new Subscription();

上記のように定義すれば、

this.subscription.add(
  Observableを作成する処理
);

という形で、1つのSubscriptionオブジェクトに複数のObservableを追加し、一括管理できるようになります。


Subjectとは

日本語で議題、主題といった意味で、RxJSにおいては以下の特徴を持つObservableの一種です。

  • 複数のObserverに同時にデータ配信するマルチキャストが可能

  • 値をpush(配信)可能

例えば以下のように、あるSubjectオブジェクトから値が配信された時にObservableをunsubscribeする、といった処理の実装に使えます。


SubscriptionとSubjectの使い方

以下はObservableを生成するメソッドにおいて、実行前に以前のObservableへの購読を停止するようにしたものです。これにより、メソッドが何回も呼び出されても、このObservableが複数存在しないようにできます。

public destroy$ = new Subject();
public subscription = new Subscription();

pushNumber(): void {
  // this.destroyが値を発行することでtakeUntilを起動し、既存の購読をキャンセルする
  this.destroy$.next();
  this.subscription.add(
    interval(30000)
      .pipe(
        takeUntil(this.destroy$),
      )
      .subscribe(number => {
        console.log(number);
      })
  );
}

destroy$がSubjectオブジェクトで、値の配信に使います。「$」はそのオブジェクトがObservableであることを示すための慣例です。

interval(30000)でObservableを作成しています。ここでは30,000ミリ秒(30秒)ごとに0から始まる整数を発行します。これはRxJSで提供される関数です。

takeUntil(this.destroy$)は、this.destroy$が値を発行したら自動的にunsubscribe(解除)します。これはRxJSで提供される関数です。

少し上に戻ってthis.destroy$.next()でdestroy$オブジェクトが値を発行します。ここでは値自体はnullで、発行されたことのみが通知されます。これにより、takeUntilが現在の購読をunsubscribeします。


また、上記はpushNumberで生成されるObservableの購読を停止する処理になっています。しかしsubscriptionオブジェクトで一括管理もしているので、以下のように一括unsubscribe()も可能です。

this.subscription.unsubscribe();

ただ、これだと同じsubscriptionオブジェクトに入っている他のObservableもunsubscribeされてしまいます。

ページを離れる際などは一括unsubscribeできると便利です。

一方で細かい制御をしたい時にはSubjectオブジェクトをうまく使うと良さそうですね。


ここまでお読みいただきありがとうございました!


この記事が気に入ったらサポートをしてみませんか?