发布observable使其*热*

时间:2016-12-27 00:13:04

标签: node.js rxjs rxjs5

我正在尝试创建一个不需要订阅的热门观察。这是一个库,我想让用户能够调用某些方法,并且无需调用subscribe()来触发可观察对象。最初我有这个:

const q = new Queue();

q.add('foo bar baz').subscribe();   // <<< need to call subscribe


Queue.prototype.add = Queue.prototype.enqueue = function (lines) {

    lines = _.flattenDeep([lines]);

    var lockAcquired = false;

    return this.init()
        .flatMap(() => {
            return acquireLock(this)
        })
        .flatMap(() => {
            lockAcquired = true;
            return appendFile(this, lines)
        })
        .flatMap(() => releaseLock(this))
        .catch(err => {
            if (lockAcquired) {
                return releaseLock(this);
            }
            else {
                return makeGenericObservable();
            }
        })


};

为了让观察变得热烈,我想我可以这样做:

const q = new Queue();

q.add('foo bar baz');  // <<< don't call subscribe

Queue.prototype.add = Queue.prototype.enqueue = function (lines) {

    lines = _.flattenDeep([lines]);

    var lockAcquired = false;

    return this.init()
        .flatMap(() => {
            return acquireLock(this)
        })
        .flatMap(() => {
            lockAcquired = true;
            return appendFile(this, lines)
        })
        .flatMap(() => releaseLock(this))
        .catch(err => {
            if (lockAcquired) {
                return releaseLock(this);
            }
            else {
                return makeGenericObservable();
            }
        })
        .publish()
        .share()  // this too?

};

然而问题是当我调用publish()时,没有任何反应,并且add方法似乎永远不会被完全调用(我假设序列中的第一个observable根本不会触发,因为没有调用有效订阅) 。但我虽然publish()会自动调用可观察链?

如何从add方法 hot 返回observable?

2 个答案:

答案 0 :(得分:2)

你误解了。 Hot observable 需要订阅,就像冷的一样。区别在于hot使用一些外部生产者(如dome元素)并开始在订阅时收听它。另一方面,cold observable在订阅时在内部创建生产者。

这导致你可以错过一些具有热观察的事件,因为外部生产者对订阅一无所知并且独立发出。在冷可观察的情况下,您不能错过任何内容,因为生产者是在订阅时创建的。

长话短说,你可以建立任何可观察的热链或冷观察链,但在你订阅之前,什么都不会发生。

PS。无需将publishshare一起使用,因为.publish().refCount()后者为alias

答案 1 :(得分:1)

如果您不想使用subscribe,则可以手动.connect()您的信息流或subscribe在您的方法中:

const q = new Queue();
q.add('foo bar baz');

Queue.prototype.add = Queue.prototype.enqueue = function (lines) {
    lines = _.flattenDeep([lines]);
    var lockAcquired = false;

    let add$ = this.init()
        .flatMap(() => {
            return acquireLock(this)
        })
        .flatMap(() => {
            lockAcquired = true;
            return appendFile(this, lines)
        })
        .flatMap(() => releaseLock(this))
        .catch(err => {
            if (lockAcquired) {
                return releaseLock(this);
            }
            else {
                return makeGenericObservable();
            }
        })
        .publish();

     add$.connect();
     return add$;  // optional, depends if you even need the stream outside of the add-method
};

或作为使用内部subscribe的替代方法:

const q = new Queue();
q.add('foo bar baz');  // <<< don't call subscribe

Queue.prototype.add = Queue.prototype.enqueue = function (lines) {
    lines = _.flattenDeep([lines]);
    var lockAcquired = false;
    let add$ = this.init()
        ...
        .share();

     add$.subscribe();
     return add$;
};