2015-12-12 16 views
7

私は、特定の状態になるまでRxJsをObservableにループさせようとしています。具体的には、同期do/whileループをRxJsに変換していますが、forやwhileループでも同じ答えが使用できると仮定しています。RxJs:観測対象の状態に基づいてどのようにループするのですか?

私はこれにdoWhile()を使うことができると思っていましたが、条件関数がストリーム内のアイテムにアクセスできないように思えます。

私は正しい反応性の用語は、私が欲しいものですが、ここで私はつもりかの例が何であるかを完全にはよく分からない:

var source = new Rx.Observable.of({val: 0, counter: 3}); 

source.map(o => { 
    o.counter--; 
    console.log('Counter: ' + o.counter); 

    if (!o.counter) { 
    o.val = "YESS!"; 
    } 
    return o; 
}) 
.doWhile(o => { 
    return o.counter > 0; 
}) 
.subscribe(
    function (x) { 
     console.log('Next: ' + x.val); 
    }, 
    function (err) { 
     console.log('Error: ' + err); 
    }, 
    function() { 
     console.log('Completed'); 
    }); 

予想される出力は次のようになります。

Counter: 3 
Counter: 2 
Counter: 1 
Counter: 0 
Next: YESS! 
Completed 

これは解決可能な問題であると仮定し、ループ時に戻したい場所の「開始」をどのようにマークするかは不明です。

答えて

7

expand演算子があります。セレクタ関数を再帰的に呼び出すことができます。空の観察可能なものを返すことは、その場合のあなたの休憩でしょう。 jsbinを参照してください:

var source = Rx.Observable.return({val: 0, counter: 3}) 
    .expand(value => { 
     if(!value.counter) return Rx.Observable.empty(); 
     value.counter -= 1; 
     if(!value.counter) value.val = 'YESS'; 
     return Rx.Observable.return(value) 
    }) 
    .subscribe(value => console.log(value.counter ? 
            'Counter: ' + value.counter : 
            'Next: ' + value.val)); 
+0

ハム。興味深いことに、私はその仕事をすることができるかもしれませんが、もし私が.expand()を実行した場合は、これを使って – JBCP

+0

を返信しようとします。 y下流マップは、値を複数回処理することになります。私は下流が最終結果だけを処理するようにしたい。私はexpand()。filter()。map()がうまくいくかもしれないと思います。 – JBCP

+0

Hm。下流に複数の値を渡すことを回避できるようにすることを念頭に置く他の唯一の方法が課題です。私はそれ自身のクリーンなソリューションに興味があります:)。 –

5

ない正確に何をしたいが、近く、expand演算子を使用して、そしてRx.Observable.emptyhttp://jsfiddle.net/naaycu71/3/)と再帰の終了を知らせる:

var source = new Rx.Observable.of({val: 0, counter: 3}); 

source.expand(function(o) { 
    console.log('Counter: ' + o.counter); 
    o.counter--; 

return (o.counter >= 0) ? Rx.Observable.just(o) : Rx.Observable.empty() 
}) 
.subscribe(
    function (x) { 
     console.log('Next: ' , x); 
    }, 
    function (err) { 
     console.log('Error: ' + err); 
    }, 
    function() { 
     console.log('Completed'); 
    }); 

出力:

Next: Object {val: 0, counter: 3} 
Counter: 3 
Next: Object {val: 0, counter: 2} 
Counter: 2 
Next: Object {val: 0, counter: 1} 
Counter: 1 
Next: Object {val: 0, counter: 0} 
Counter: 0 
Completed