web-dev-qa-db-ja.com

.unsubscribeと.take(1)の違い

サブスクリプションの直後にunsubscribeが使用されているときに、.take(1).unsubscribeを使用してパフォーマンスに違いがあるのではないかと思います。

var observable = Rx.Observable.interval(100);

最初:

var subscription = observable.subscribe(function(value) {
   console.log(value);
}).unsubscribe();

第二:

var subscription = observable.take(1).subscribe(function(value) {
    console.log(value);
});

それについてのアイデアは、パフォーマンスに関して何か違うことをしますか?

45
TheUnreal

それぞれが異なる目的を果たすため、それらを比較するのは困難です。

一般に、このソースを使用する場合:

_const source = range(1,3);
_

... subscribe()に続けてすぐにunsubscribe()を続けて使用します。

_source.subscribe(
  console.log,
  undefined, 
  () => console.log('complete')
).unsubscribe();
_

...購読直後にunsubscribe()を呼び出した場合でも、sourceからのすべての値が出力されます。これは、コードが依然として厳密にシーケンシャル(同期)であり、sourceがコールドオブザーバブルであるためです。

_1
2
3
complete
_

ところで、delay(0)を作るためにsource.pipe(delay(0)).subscribe(...).unsubscribe()演算子を追加してみてください。これにより、実際のsetTimeout()呼び出しを使用して値を非同期に発行するため、nextハンドラーの前にunsubscribe()が呼び出され、すぐに破棄されます。

言い換えると、unsubscribe()はいつでも値の受信を停止できるようにします。ソースが値を発行していなくても(完全な通知を受け取ることはありません)。

take()演算子を使用すると、チェーンが特定の数の値のみを出力するように制限されます。

_source.pipe(
  take(1),
)
.subscribe(
  console.log,
  undefined,
  () => console.log('complete')
);
_

これはただ一つの値を出力して完了します:

_1
complete
_

.unsubscribe()を追加しても、結果は同じになります。

ライブデモをご覧ください: https://stackblitz.com/edit/rxjs-tbu5kb

したがって、take()は演算子であり、unsubscribe()Subscription オブジェクトのメソッドです。多くの場合、これらの2つのことは互換性がありますが、完全に互いを置き換えることはありません。

2019年1月:RxJS 6用に更新

85
martin

take(1)は、コンポーネントが破棄されている場合でもまだ登録解除されないことに注意してください。サブスクリプションは、コンポーネントがアクティブであるか破棄されているかに関係なく、最初の値が発行されるまでアクティブのままです。そのため、サブスクリプションでDOMにアクセスするなど、もっとクレイジーな操作を行うと、コンソールでエラーが発生する可能性があります。 https://blog.angularindepth.com/the-best-way-to-unsubscribe-rxjs-observable-in-the-angular-applications-d8f9aa42f6a

8
el peregrino