web-dev-qa-db-ja.com

RXJS-Angular-サブジェクトからの退会

this thread で説明されているように、Angular 5+一般にObservablesから登録解除するための「公式」ソリューションは、takeUntilを使用しています。これまでのところ、とても良いです。私の質問は、これは、私がサブスクライブしているオブザーバブルが実際にサブジェクトである場合にも適用されますか?

4
didgewind

何か(サブジェクトも)で.subscribe()を呼び出すと、サブスクリプションがサブスクライブ解除されるようにする必要があります。

有限オブザーバブルとの取引:有限オブザーバブル(有限/制限シーケンスを持つオブザーバブルを意味する)にサブスクライブすると、最後のメッセージが終了信号を送信し、サブスクリプションは自動的にキャンセルされます。この例は次のとおりです。

_Observable.of(100)
Observable.from([1,2,3,4])
_

in有限のオブザーバブルの例:

_Observable.fromEvent(document, 'click')
Observable.timer(1000)
_

オブザーバブルで.first().take(number)または.takeWhile(condition that will evaluate to false at some point)またはtakeUntil(observable that emits a value)を呼び出す/パイピングすると、それ以外の場合は無限のオブザーバブルが有限オブジェクトに変換されます。

。subscribe()の呼び出しを停止する:登録解除の必要がないもう1つの一般的な方法は、最初に登録しないことです。いつサブスクライブしないオブザーバブルが必要になるので、これは愚かに聞こえるかもしれません。まあ、view/htmlテンプレートに一部のデータを渡すだけでよい場合は、監視可能な非同期パイプへのパイプにより、購読解除の問題が非同期パイプ自体に渡されます。

HTMLテンプレートの典型的な例:

_<h1>Editing {{ infiniteObservable$ | async }}<h1>
<li *ngFor="let user of userObservable$ | async as users; index as i; first as isFirst">
   {{i}}/{{users.length}}. {{user}} <span *ngIf="isFirst">default</span>
</li>
_

手動で登録解除:最後に、すべてのサブスクリプションへの参照を保持するように選択できます。変数を各サブスクリプションを指すようにする必要はありません。単一のSubscriptionオブジェクトを使用してすべてのサブスクリプションを追跡し、それらすべてを一度にサブスクライブ解除する方が簡単です。次に例を示します。

_const subscriptions = new Subscription();
subscriptions.add(observable1$.subscribe());
subscriptions.add(observable2$.subscribe());
subscriptions.unsubscribe();
_

Quick summerize、サブスクリプション解除の処理方法、以下のいずれかの方法:

  1. 無限のオブザーバブルを有限のものに変換します。これにより、サブスクライブを解除する必要がなくなります(.takeUntil(this.destroyed$)を使用し、this.destroyed$.emit()ngOnDestroy()を実行します)。
  2. サブスクライブを避け、asyncパイプを介してオブザーバブルを渡すことは避けてください。
  3. サブスクリプションへの参照を保持し、.unsubscribe()メソッドでngOnDestroy()を呼び出します。

個人的には、最初の2つの方法のうち1つだけを使用する傾向があります。

追加するものがあります。 Subjectはサブスクライバーを内部に格納します(Observableも同様です)。 Subjectがコンポーネントの一部である場合(内部で作成され、プロパティとして格納されるか、クロージャーに格納されます)、サブジェクトとそのサブスクリプションはコンポーネント自体でガベージコレクションされます。

ただし、これは特別なケースであり、非常に注意する必要があります。すべてがコンポーネントに含まれている必要があります。

それは例えば安全ですnotFormControl.valueChangesオブザーバブルがコンポーネントでのみ使用されている場合は、それをサブスクライブ解除します。

しかし、安全のために、それについて考えたくない場合は、takeUntilを使用してください。

0
ribizli