2016-08-17 8 views
4

自分の「購読」を宣言して順番に実行するようにRxJSパターンを理解しようとしています。ここでRxJS - Fireが順番に購読する

は私がにいる状況だ:

var flag = false; 

// Stream that non-deterministically emits `true` when flag is true 
var random$ = Rx.Observable.interval(1000) 
    .map(() => setFlagToRandomTrueOrFalse()) 
    .filter(x => x) 
    .first(); 

// How can I declare my "subscribes" so that the console.logs happen in order? 
var sub1 = random$.subscribe(() => console.log(1), console.log, resetFlagToFalse); 
var sub2 = random$.subscribe(() => console.log(2), console.log, resetFlagToFalse); 

function setFlagToRandomTrueOrFalse() { 
    flag = flag || !!Math.floor(Math.random() * 2); 
    return flag; 
} 

function resetFlagToFalse() { flag = false; } 

これは、現在.subscribeの非同期性質によるランダムな順序で12を出力します。

また、これらの「サブスクライブ」の正しい名前は何ですか? RxJSの合計はここにあります。

+0

順序が重要な場合はサブスクライブ、それらを単一に構成すべきではありませんか? – cartant

+0

私はサブスクリプションの 'onNext'内でサブスクライブをネストすることを避けたいと考えていました。これは単なる例であり、 'flag'は実際には別のライブラリによって管理されるブール値です。 –

答えて

1

あなたは私はあなたが観察順序が原因subscribeの非同期性質のものであることを確認していないこの

var flag = false; 
 

 
// Stream that non-deterministically emits `true` when flag is true 
 
var random$ = Rx.Observable.interval(1000) 
 
    .map(() => setFlagToRandomTrueOrFalse()) 
 
    .filter(x => x) 
 
    .first().publish(); 
 

 
// How can I declare my "subscribes" so that the console.logs happen in order? 
 
var sub1 = random$.subscribe(() => console.log(1), console.log, resetFlagToFalse); 
 
var sub2 = random$.subscribe(() => console.log(2), console.log, resetFlagToFalse); 
 

 
random$.connect(); 
 

 
function setFlagToRandomTrueOrFalse() { 
 
    flag = flag || !!Math.floor(Math.random() * 2); 
 
    return flag; 
 
} 
 

 
function resetFlagToFalse() { flag = false; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/4.1.0/rx.all.js"></script>

2

eeerrのような順序でアクションを実行するためにpublish() and connect()を使用することができます。まず、現時点で書かれているように、random$は低温源、すなわち未だ購読されていない生産者である。そのプロデューサーは、あなたがそれを購読するたびにプロダクションを開始します。つまり、ここではプロデューサーを2回開始しているので、2つの異なるランダムな値がそれぞれ別々に出力されるので、ログが異なる時刻に表示されます。同じシーケンスの値を購読していなければ非常にそうです。

寒い流れと熱い流れの区別のより明確な説明はHot and Cold observables : are there 'hot' and 'cold' operators?です。このことを理解するために必要な時間を費やすことは、Rxjsで何か面白いことを始める前にこれが非常に重要であるためです。

同じ値のシーケンスをサブスクライブする場合、つまり、プロデューサですべてのサブスクライバに値をマルチキャストする(ホット動作)場合は、各サブスクライバ(コールドビヘイビア)に対して再起動するのではなく、前述のリンクで説明したように、multicastオペレータのバリエーションです。それが戻ってデータ伝播順序についての質問に行くあなたのケース

var random$ = Rx.Observable.interval(1000) .map(() => setFlagToRandomTrueOrFalse()) .filter(x => x) .share();

に意味、それは常に簡単なわけない、確かにほとんど決定的です。単純なケースでは、最初のサブスクリプションが実際に最初に実行されます。なぜなら、フードの下では、multicastのような演算子がサブジェクトを使用しているからです。サブジェクトは、サブスクリプション順にすべてのサブスクライバに受け取った値をすぐに(ホット・ソース)放出します。科目については、What are the semantics of different RxJS subjects?をご覧ください。

最後のことは、純粋な機能を構成する場合、ストリームを推論するのに役立ちます。 flagのようなクロージャー変数を持つことは、非常に速く複雑になります。

私はRxjsにずっとさらに踏み込んで前にここを見てすることをお勧めいたします:The introduction to Reactive Programming you've been missing

関連する問題