2016-06-22 1 views
2

私はこのペンを作成します。 http://codepen.io/hatelove85911/pen/Vjmwwb熱く観測できるのはいつ最初の値を出しますか?

const Ob = Rx.Observable 
const button = document.querySelector('#click') 

const count$ = Ob.fromEvent(button, 'click') 
       .scan(acc=>++acc,0) 
       .share() 
setTimeout(()=>{ 
    count$.subscribe(x=>console.log('sub1:',x)) 
},5000) 

setTimeout(()=>{ 
    count$.subscribe(x=>console.log('sub2:',x)) 
},10000) 

すべてのオンラインの記事には、加入者がありません場合でも、ホット、観察開始が値を発することを言います。

この例では、私はそれを熱くするために観測値を共有しました。 最初のサブスクライバの前に1より大きい累積値を得ることを期待して、ボタンを数回クリックし続けますが、最初のサブスクライバが来ると、そのログは1から開始しますが、2番目のサブスクライバのログは中間から開始します、1からではありません。

誰かがこれがなぜ起こっているのか説明できますか?

+0

私はrxjsにはあまり慣れていませんが、どこが暑くて寒くないのかを指定していますか? – paul

+0

私は、デフォルトでは、ボタンのクリックは熱くなるはずだと思いますよね?加入者の有無にかかわらず、ボタンはまだクリックされているためです。私は '.share()'メソッドを使って、それが暑いことを確認しました。 –

答えて

3

ホット/温かい/冷たい用語は常に混乱になるだろう。私はフードの中で何が起きているのかを正確に理解するために気温の比喩を逃れようとします。

基本的に、すべての(Rxjs)観測値(を除いて)は怠惰です。つまり、加入者がいない場合(オブザーバーとも呼ばれる)、データフロー(または実際には何もない)が存在しないことを意味します。サブスクリプションで発生したサブスクリプションとデータフローの詳細な説明がここにあります:Hot and Cold observables : are there 'hot' and 'cold' operators?

shareは観測可能であり、観測可能でもありません。したがって、プロデューサー(あなたのオペレーター連鎖によって明らかにされる)は最初のサブスクリプションではじめて開始されます。したがって、サブスクリプションの前にクリックしても、何も実行されません。一度購読すると、プロデューサーが実行され、オブザーバー/サブスクリプションは値1を生成します。

あなたがリンクされ図示されたデータフローで見ることができるように、shareはそうOb.fromEvent(button, 'click').scan(acc=>++acc,0)がそれに加入主題を持っているpublishmulticast(new Rx.Subject())あるpublish().refCount()の別名です。ここで重要なのは、サブジェクトが実際にはサブスクリプションされていないことですが、connect()にコールするときにはサブジェクトになります。被験者が購読したら、値がに到達した時点で、それが登録された観察者に受信した値をすべてに渡します。それは、ホットな行動であると考えられる行動です。混乱する部分は、熱い観察可能なものが観察可能であり、それゆえにまだ怠け者であることです(怠け者ではないものを除いて)。

詳細については、publishは接続可能な観測可能(まだレイジー)を返します。あなたがそれを購読するとき、あなたは上記の主題に加入しています。しかし、あなたがconnect()をしていない限り、そのサブジェクトはそれ自体が観測可能なソースに登録されていません。したがって、データは流れません。

であなたのcodepenを置き換え、これをあなたに納得させる:だからobs.publish(); obs.subscribe(observer1)で短期的に、あなたが接続する前a-->bb is subscribed to aを意味し、次の状態obs | subject -> observer1を持って

const Ob = Rx.Observable 
const button = document.querySelector('#click') 

const count$ = Ob.fromEvent(button, 'click') 
       .scan(acc=>++acc,0) 
       .publish(); 
setTimeout(()=>{ 
    count$.subscribe(x=>console.log('sub1:',x)) 
},1000) 


setTimeout(()=>{ 
    count$.subscribe(x=>console.log('sub2:',x)) 
    count$.connect(); 
},5000) 

。サブジェクトは受信した値だけを渡し、受信していないため、どのソースにもサブスクライブしていないため、データは流れません。

connect()の場合は、状態はobs -> subject -> observer1です。したがって、obsプロデューサーが開始し、その値を受け取った瞬間に観測者に値を送信するサブジェクトに値を送信します。

+0

お返事ありがとうございました。今私はこのすべてを理解することを知っている、私はその背後にある実装を理解する必要があります。熱いものや冷たいものは本当に混乱しています。また、良い資料がデータの流れを詳細に説明していないので混乱しています。 –

+0

これらを確認することはできますか:1.フードの下で熱く観測可能な手段は、すべてソースから加入者への値をマルチキャストするための仲介者として主題を使用します。 2.暑いか寒いかに関係なく、少なくとも1人の加入者がいるときだけ価値を出すでしょう。 3.多くのオンライン投稿が間違っている、彼らは熱い観察可能な値は、加入者があるかどうかにかかわらず、ホット観測可能な少なくとも1つの加入者がある場合にのみ値を発するかどうかにかかわらず、 –

+0

Rxjsで定義されているjavascriptオブジェクトを観測可能ならば、1にします.2人の被験者の1つの警告は、加入者がいない(つまり、怠惰ではない)ときでも、 (オブザーバーも同様)。何が起きるのは、JavaScriptのオブジェクトではなく、ソース自体(例えば、クリックのシーケンスとこのシーケンスを表すjavascriptオブジェクトの順番:オブジェクトは、クリックのシーケンスがあなたが聞いているかどうかにかかわらず起こる)。 – user3743222

1

私はRxJSも新しくなっていますが、fromEventは「暖かい」Observableのような感じです。基本的には、実際のサブスクリプションが発生するまでは追跡が始まらないという点で怠惰です。 shareは一度購読してしまえば暑いですが、その怠惰のために最初の購読までは何も追跡されないので、それはまだその意味で "暖かい" Observableです。

最初のサブスクリプションの前にクリックが追跡され、.publish()(ConnectableObservablesを返す)を使用してからすぐに.connect()を使用することができます。

Codepen.io Example

const Ob = Rx.Observable 
const button = document.querySelector('#click') 

const count$ = Ob.fromEvent(button, 'click') 
       .scan(acc=>++acc,0) 
       .publish(); // <-- publish here 

count$.connect(); // <--immediately connect to it 

setTimeout(()=>{ 
    count$.subscribe(x=>console.log('sub1:',x)) 
},5000) 


setTimeout(()=>{ 
    count$.subscribe(x=>console.log('sub2:',x)) 
},10000) 
関連する問題