2017-02-03 6 views
6

私は、マルチキャストされた観測可能性と私が気づいた予期せぬ(私にとっては)動作に関する質問があります。共有observableとstartWith演算子

const a = Observable.fromEvent(someDom, 'click') 
    .map(e => 1) 
    .startWith(-1) 
    .share(); 

const b = a.pairwise(); 

a.subscribe(a => { 
    console.log(`Sub 1: ${a}`); 
}); 

a.subscribe(a => { 
    console.log(`Sub 2: ${a}`) 
}); 

b.subscribe(([prevA, curA]) => { 
    console.log(`Pairwise Sub: (${prevA}, ${curA})`); 
}); 

したがって、すべてのクリックイベントで1を発生する共有観測可能なaがあります。 -1はstartWith演算子のために送出されます。 観測可能なbは、aからの最新の2つの値をペアにすることによって、新しい観測値を作成するだけです。

私の期待があった。

[-1, 1] // first click 
[ 1, 1] // all other clicks 

私は何を観察することだった:私は気づいた何

[1, 1] // from second click on, and all other clicks 

もサブ2は前の値が-1、1 Subのことで、すぐに放出されて消費されていることですObservableにサブスクライブし、aがマルチキャストされているため、Sub 2はパーティーには遅すぎます。

私はBehaviourSubject経由でマルチキャストでき、startWith演算子を使用できないことを知っていますが、startWithを使用して共有経由でマルチキャストすると、このシナリオの使用例を理解したいと思います。他のすべての加入者が値を放出した後に加入しているので、

は、私の知る限り理解し、私は.share()と.startWith(X)を使用するとき、唯一の加入者は、startWith値について通知されます。

これは、特定のテーマ(ビヘイビア/リプレイ...)を介してマルチキャストする理由ですか、このstartWith/shareシナリオについて何か不足していますか?

ありがとうございます!

+0

私は同じ問題に直面しています。 BehaviourSubjectの例を挙げてください。 – Eselfar

答えて

7

これは実際には正しい動作です。

.startWith()は、最初のものだけでなく、すべての新しい加入者にその価値を発信します。​​が受信しない理由は、.share()(別名.publish().refCount())のマルチキャストを使用しているためです。

これは、最初のa.subscribe(...)がそのソースに登録することを意味し、購読し続けることになります(Observable .fromEvent(someDom, 'click')は完了しません)。

次に、あなたが最終的にb.subscribe(...)を呼び出すときには、.share()内のみSubjectに加入しましょう、それがマルチキャストとすでに.share()に加入しているため.startWith(-1)を通過することはありません。

+0

ねえ!それは私が理解したものでもありました。なぜ観測が理にかなっているかについて詳しく説明してくれてありがとう。このシナリオの1つの解決策は、サブスクリプションを設定した後、接続可能なオブザーバブルとコール接続を使用することです。このようにして、すべての加入者はstartWith値を取得します。 – dinony

関連する問題