41

RxJs 5share()オペレーターがどのように機能するかは、100% 明確ではありません。こちらの最新のドキュメントを参照してください。ここでの質問の Jsbin 。

一連の 0 から 2 でオブザーバブルを作成すると、各値は 1 秒で区切られます。

var source = Rx.Observable.interval(1000)
.take(5)
.do(function (x) {
    console.log('some side effect');
});

このオブザーバブルに 2 つのサブスクライバーを作成すると、次のようになります。

source.subscribe((n) => console.log("subscriptor 1 = " + n));
source.subscribe((n) => console.log("subscriptor 2 = " + n));

コンソールでこれを取得します:

"some side effect ..."
"subscriptor 1 = 0"
"some side effect ..."
"subscriptor 2 = 0"
"some side effect ..."
"subscriptor 1 = 1"
"some side effect ..."
"subscriptor 2 = 1"
"some side effect ..."
"subscriptor 1 = 2"
"some side effect ..."
"subscriptor 2 = 2"

各サブスクリプションは同じ Observable にサブスクライブすると思っていましたが、そうではないようです! サブスクライブするという行為は、完全に別の Observable を作成するようなものです!

ただし、share()オペレーターがソース オブザーバブルに追加されている場合:

var source = Rx.Observable.interval(1000)
.take(3)
.do(function (x) {
    console.log('some side effect ...');
})
.share();

次に、これを取得します。

"some side effect ..."
"subscriptor 1 = 0"
"subscriptor 2 = 0"
"some side effect ..."
"subscriptor 1 = 1"
"subscriptor 2 = 1"
"some side effect ..."
"subscriptor 1 = 2"
"subscriptor 2 = 2"

これは、なしで私が期待するものshare()です。

ここで何が起こっているのですか、share()オペレーターはどのように機能しますか? 各サブスクリプションは新しい Observable チェーンを作成しますか?

4

2 に答える 2

23

ドキュメント リンクが RxJS v4 のように見える場合、RxJS v5 を使用していることに注意してください。share詳細は覚えていませんが、特に完了と再購読に関しては、オペレーターがいくつかの変更を行ったと思いますが、私の言葉を鵜呑みにしないでください。

質問に戻りますが、研究で示したように、あなたの期待はライブラリの設計に対応していません。オブザーバブルはデータフローを遅延してインスタンス化し、サブスクライバーがサブスクライブするとデータフローを具体的に開始します。2番目のサブスクライバーが同じオブザーバブルをサブスクライブすると、最初のサブスクライバーであるかのように別の新しいデータフローが開始されます(そうです、あなたが言ったように、各サブスクリプションはオブザーバブルの新しいチェーンを作成します)。これは、RxJS 用語でコールド オブザーバブルと呼ばれるものであり、RxJS オブザーバブルのデフォルトの動作です。データが到着した時点でサブスクライバーにデータを送信するオブザーバブルが必要な場合、これはホット オブザーバブルと呼ばれます。ホット オブザーバブルを取得する 1 つの方法は、shareオペレーターを使用することです。

図解されたサブスクリプションとデータ フローをここで見つけることができます: Hot and Cold observables: are there 'hot' and 'cold' operator? (これは RxJS v4 で有効ですが、ほとんどは v5 で有効です)。

于 2016-02-01T22:47:54.430 に答える