私は次の SO の質問を確認しました:ホット観測値とコールド観測値とは何ですか?
要約する:
- コールド オブザーバブルは、その値を消費するオブザーバーが存在する場合にその値を発行します。つまり、オブザーバーが受け取る値のシーケンスは、サブスクリプションの時間に依存しません。すべてのオブザーバーは同じ値のシーケンスを消費します。
- ホット オブザーバブルはサブスクリプションとは独立して値を発行します。つまり、オブザーバーが受信する値はサブスクリプションの時間の関数です。
しかし、暑いか寒いかは依然として混乱の原因になっているように感じます。そこで、私の質問は次のとおりです。
すべての rx 観測可能オブジェクトはデフォルトでコールドですか (サブジェクトを除く)?
Rx.fromEvent(input, 'click')
イベントはホット オブザーバブルの典型的なメタファーであるとよく読みますが、コールド オブザーバブル(?)であるとも読みます。コールド オブザーバブルをホット オブザーバブルに変換する Rx 演算子はありますか (
publish
、および 以外share
)?たとえば、Rx 演算子ではどのように動作するのでしょうか
withLatestFrom
?cold$
をどこかでサブスクライブされているコールド オブザーバブルとします。 をsth$.withLatestFrom(cold$,...)
ホット オブザーバブルとします。または、と
sth1$.withLatestFrom(cold$,...), sth2$.withLatestFrom(cold$,...)
を実行して をサブスクライブすると、常に両方に同じ値が表示されますか?sth1
sth2
sth
冷たい観測可能なものを作成すると思いました
Rx.fromEvent
が、回答の 1 つに記載されているように、そうではありません。しかし、私はまだこの動作に困惑しています。https://codepen.io/anon/pen/NqQMJR?editors=101異なるサブスクリプションは、同じオブザーバブルから異なる値を取得します。click
イベントは共有されませんでしたか?
ベストアンサー1
数か月後に元の質問に戻り、その間に得た知識を共有したいと思いました。説明のサポートとして次のコードを使用します(jsfiddle):
var ta_count = document.getElementById('ta_count');
var ta_result = document.getElementById('ta_result');
var threshold = 3;
function emits ( who, who_ ) {return function ( x ) {
who.innerHTML = [who.innerHTML, who_ + " emits " + JSON.stringify(x)].join("\n");
};}
var messages$ = Rx.Observable.create(function (observer){
var count= 0;
setInterval(function(){
observer.onNext(++count);
}, 1000)
})
.do(emits(ta_count, 'count'))
.map(function(count){return count < threshold})
.do(emits(ta_result, 'result'))
messages$.subscribe(function(){});
回答の 1 つで述べたように、オブザーバブルを定義すると、一連のコールバックとパラメータ登録が必要になります。データ フローを開始する必要があり、これは関数を介して行われますsubscribe
。その後に、(説明のために簡略化された) 詳細なフローが示されます。
オブザーバブルはデフォルトではコールドです。オブザーバブルをサブスクライブすると、アップストリームのサブスクリプション チェーンが実行されます。最後のサブスクリプションにより、ソースを処理してそのデータをオブザーバーに送信する関数が実行されます。
そのオブザーバーは、次に次のオブザーバーに送信し、シンク オブザーバーまでのダウンストリーム データ フローを生成します。次の簡略化された図は、2 つのサブスクライバーが同じオブザーバブルをサブスクライブする場合のサブスクリプションとデータ フローを示しています。
ホット オブザーバブルは、サブジェクトを使用するか、演算子multicast
(およびその派生語、以下の注 3 を参照) を通じて作成できます。
オペレータは内部multicast
でサブジェクトを利用し、接続可能なオブザーバブルを返します。オペレータへのすべてのサブスクリプションは、内部サブジェクトへのサブスクリプションになります。がconnect
呼び出されると、内部サブジェクトは上流のオブザーバブルにサブスクライブし、データは下流に流れます。サブジェクトは、サブスクライブされたオブザーバーのリストを内部的に操作し、受信データをすべてのサブスクライブされたオブザーバーにマルチキャストします。
次の図は状況をまとめたものです。
最終的には、オブザーバー パターンと演算子の実装によって発生するデータの流れを理解することがより重要になります。
たとえば、obs
が暑い場合、hotOrCold = obs.op1
寒いですか、それとも暑いですか? 答えが何であれ:
- に加入者がいない場合は
obs.op1
、データは を通過しませんop1
。 に加入者がいた場合はobs
、obs.op1
データが失われる可能性があります。 op1
がマルチキャストのような演算子ではないと仮定すると、 を 2 回サブスクライブするhotOrCold
と も 2 回サブスクライブされop1
、 からのすべての値はobs
を 2 回通過しますop1
。
ノート :
- この情報は Rxjs v4 に有効です。バージョン 5 では大幅に変更されていますが、そのほとんどがそのまま適用されます。
- サブスクリプション解除、エラー、完了フローは質問の範囲外であるため、表示されません。スケジューラも考慮されません。特に、スケジューラはデータ フローのタイミングに影響しますが、その方向と内容には事前に影響しません。
- マルチキャストに使用されるサブジェクトのタイプに応じて、派生したさまざまなマルチキャスト オペレータが存在します。
Subject type | `Publish` Operator | `Share` operator ------------------ | --------------------------- | ----------------- Rx.Subject | Rx.Observable.publish | share Rx.BehaviorSubject | Rx.Observable.publishValue | shareValue Rx.AsyncSubject | Rx.Observable.publishLast | N/A Rx.ReplaySubject | Rx.Observable.replay | shareReplay
アップデート: 参照以下の記事はこちら、 そしてそこに(ベン・レッシュによるそのテーマに関する記事)
主題に関する詳細は、次の他の SO の質問で確認できます。さまざまな RxJS サブジェクトのセマンティクスは何ですか?