私はこのようなパターンを見てきました:
_Observable<String> nameChanges = nameDataSource.changes().share();
// One subscriber
autoUnsubscribe(nameChanges.subscribe(() -> { ... }));
// Another subscriber
autoUnsubscribe(nameChanges.map(...).filter(...).subscribe(...));
// autoUnsubscribe is called when the UI is torn down
_
私の質問は:
複数の場所でObservableを聴きたいときに、なぜshare()
を呼び出す必要があるのですか?
share()
がすべてのオブザーバブルのデフォルトの動作ではないのはなぜですか?
上記のコードが.share()
がなくても同じように機能するのは素晴らしいことです。いつObservableを共有する必要があるのか、いつ共有しないのかを考える必要はありません。
単一のサブスクライバーを持つことは、より効率的に処理できる特殊なケースであるため、パフォーマンス上の理由ですか?
ドキュメントから、これは私には明らかではありません:
share()は、元のObservableSourceをマルチキャスト(共有)する新しいObservableSourceを返します。少なくとも1つのオブザーバーが存在する限り、このObservableSourceはサブスクライブされ、データを発行します。
Observable
sには、コールドとホットの2種類があります。 ColdObservable
sは、Observer
が存在するときにアイテムの作成を開始し、個別に作成します。複数のObserver
sでサブスクライブすると、同じコールドObservable
が複数回実行されます。この例は、ネットワーク要求を発行するObservable
です。
対照的に、hotObservable
は、Observer
sの存在の有無にかかわらずアイテムを生成できます。これらのObservable
sは通常、同じアイテムを現在のすべてのObserver
sにマルチキャストします。この例は、ボタンクリックのObservable
です。
コールドObservable
をホットなものに変えるには、publish()
を使用できます。これにより、Observable
の数に関係なく、ソースObserver
に対して単一のサブスクリプションのみが確立されます。 $ var] _sあります。したがって、チェーンはObservable
sの観点からホットマルチキャストObserver
として機能するようになります。
ただし、多くの場合、publish()
のすべてのObservable
がなくなった後、元のコールドObserver
を実行し続けることは経済的ではないため、refCount()
演算子は次のことができます。それらを追跡し、興味深いパーティが残っていないときにソースを停止するために使用されます。
ソースがすでにホットな場合は、share()
は必要ありません。
Share()がすべてのオブザーバブルのデフォルトの動作ではないのはなぜですか?
実際、このプロパティは、最新のリアクティブプログラミングパラダイムの重要な貢献の1つです。つまり、ホットとコールドのObservable
sの区別です。
ただし、マルチキャストは、新しいイベントを通知するために現在のObserver
のセットを追跡する必要があるため、それ自体がコストがかかります。これにより、あらゆる種類の論理的な競合状態を防ぐことができます。コールドObservable
は単一のObserver
とのみ通信することが知られているため、追加のトラッキングオーバーヘッドは必要ありません。
I would not have to think about when I need to share an Observable, and when I don't.
プログラミングの際に考えなければならないのではないかと思います。 ;)
上記のコードでは、はい、共有は理にかなっています。しかし、2つの異なるポイントから同じネットワークとメソッド呼び出しを使用し、異なるデータで更新して、バックエンドで何かを更新している場合はどうなるでしょうか。同じObservableで同じ呼び出しがありますが、確かにそうしません Observableインスタンス(およびネットワーク呼び出し)を共有したいのは、データを含むすべての連続する呼び出しがで破棄されることを意味するためです。最初のものの好意。または、サブスクライブしているときにタイマーを開始したい場合は、これを他のObservablesと共有したくないでしょう。
また、追加特定の動作は削除よりもはるかに簡単です。たとえば、共有がデフォルトであり、2番目のサブスクライバーが共有を望まず、共有を削除した場合、3番目のサブスクライバーはどうでしょうか。最初のものと共有しますか?その時点で、共有プロパティはSubscriber
ではなくObservable
のプロパティになり、どちらが共有され、どれが共有されていないかを明確に知る方法がありません。