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示例,您可能希望与take而不是一起使用(实际上有两种方法可以做同样的事情,但一种基于时间,另一种基于项目计数)。创建一个 Observable,它将收集底层 observable 的所有值,并在底层 Observable 完成时将这些值作为数组生成。bufferWithTimetoArray

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