5

RxJS を使用して、非同期のイベントの世界を同期の世界と「橋渡し」したいと考えています。具体的には、ある時間間隔で収集されたイベントの配列を返す関数を作成したいと考えています。

私が望むことをするObservableを作成できます

    var source = Rx.Observable
    .interval(100 /* ms */)
    .bufferWithTime(1000).take(1)

正しい値をうまく印刷できます

    var subscription = source.subscribe(
        function (x) {
            console.log('Next: ' + JSON.stringify(x));
        },
        function () {
            console.log('Completed');   
        });

これは印刷します

    [0,1,2,3,4,5,6,7,8] 
    Completed 

しかし、私が望むのは、この配列を変数に割り当てることです。概念的には、次のようなものが必要です

var collectedDuringSecond = source.toPromise.getValue()

getValue がブロックされるため、上記の行が完了した後、collectedDuringSecond には [0,1,2,3,4,5,6,7,8] が含まれます。

4

1 に答える 1

6

JavaScript での同期イベント プログラミングは非常に制限的です。実際、多くの場合、それは不可能かもしれません。Rx ソースを変更せずに同期インターフェースを提供できるかどうかを確認するために、Rx をいじってみましたが、(正当な理由で) そのままの JavaScript では不可能です。

Observable を API の一部として公開し、消費者がそこからそれを処理できるようにすることをお勧めします (もちろん、Rx を使用するための微調整が必​​要です;)。

function MyClass () {

    this.getArrayOfStuffAsObservable = function () {
        return Rx.Observable.interval(100)
            .bufferWithTime(1000).take(1);
    };

    // this is optional and I don't recommend it, since you already have Rx available.
    // additionally, consumers will probably miss the fact that you can dispose
    // of the subscription.
    this.getArrayOfStuff = function (callback) {
        var value;
        return this.getArrayOfStuffAsObservable()
            .subscribe(
                function (x) {
                    value = x;
                },
                function (err) {
                    callback(err);
                },
                function () {
                    if (hasValue) {
                        callback(undefined, value);
                    } else {
                        callback('did not receive value');
                    }
                });

    };
};

追加のメモとして、この特定の例の代わりにtoArrayと組み合わせて使用​​することをお勧めします(実際には同じことを行う 2 つの方法がありますが、1 つは時間に基づいており、もう 1 つは項目数に基づいています)。基礎となるオブザーバブルのすべての値を収集し、基礎となるオブザーバブルが完了するとそれらの値を配列として生成するオブザーバブルを作成します。takebufferWithTimetoArray

this.getArrayOfStuffAsObservable = function () {
    return Rx.Observable.interval(100)
        .take(10)
        .toArray();
};
于 2014-04-23T16:11:41.863 に答える