rxjs zip is not lazy?

旧时模样 提交于 2019-12-24 12:22:26

问题


I 've removed the boilerplate to get to the point

// a.js

// My observables from stream and event
this.a = Rx.Node.fromStream(this.aStream());
this.itemSource = Rx.Observable.fromEvent(ee, 'addItem');

// Zip 'em
this.itemcombo = Rx.Observable.zip(this.a, this.itemSource, function (s1, s2) {
    return {item: s2, a: s1.toString()};
});

// Streams the lowercase alphabet
rb.prototype.aStream = function aStream() {
var rs = Readable();

var c = 97;
rs._read = function () {
    rs.push(String.fromCharCode(c++));
    console.log('Hit!');
    if (c > 'z'.charCodeAt(0)) {
        rs.push(null);
    }
};

return rs;
};

// b.js (requires the module exported above)

rb.enqueue('a'); // The method simply does an ee.emit('addItem', ...)  in the module to trigger the itemSource observable

What I expected to see:

{item: 'a', a: 'a'} printed in the console

What happened:

Hit! was printed 24 times before {item: 'a', a: 'a'}. This means that zip took all the values from aStream, buffered them and then did what it was supposed to do.

How do I get the same functionality zip offers but lazily? My goal is to use an infinite stream/observable and zip it with a finite (async) one.

Edit

See/Edit it via runnable: RX Zip test Edit 2 Code updated based on answer -> no output now.


回答1:


zip is indeed lazy. It just subscribes to a and b and does its work whenever either produces a new value.

Your problem is that fromStream is emitting all of its values synchronously as soon as zip subscribes to it. This is happening because your custom Readable is constantly saying "There is more data available!"

Make your Readable asynchronous and you'll get the desired behavior.

Try something like this (untested)

var rs = Readable();
var subscription = null;
rs._read = function () {
    if (!subscription) {
        // produce the values once per second
        subscription = Rx.Observable
            .generateWithRelativeTime(
                97, // start value
                function (c) { return c > 'z'.charCodeAt(0); }, // end condition
                function (c) { return c + 1; }, // step function
                function (c) { return String.fromCharCode(c); }, // result selector
                function () { return 1000; }) // 1000ms between values
            .subscribe(
                function (s) {
                    rs.push(s);
                    console.log("Hit!");
                },
                function (error) { rs.push(null); },
                function () { rs.push(null); });
    }
};


来源:https://stackoverflow.com/questions/25524671/rxjs-zip-is-not-lazy

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!