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オブジェクトをうまく使うと良さそうですね。
ここまでお読みいただきありがとうございました!
この記事が気に入ったらサポートをしてみませんか?