分享冷热观察

时间:2015-11-14 21:16:27

标签: reactive-programming rxjs

我对使用shared创建的Rx.Observable.just信息流的行为感到困惑。

例如:

var log = function(x) { console.log(x); };

var cold = Rx.Observable
  .just({ foo: 'cold' });

cold.subscribe(log); // <-- Logs three times
cold.subscribe(log);
cold.subscribe(log);

var coldShare = Rx.Observable
  .just({ foo: 'cold share' })
  .share();

coldShare.subscribe(log); // <-- Only logs once
coldShare.subscribe(log);
coldShare.subscribe(log);

两个流只发出一个事件,但未共享的事件可以订阅三次。这是为什么?

我需要&#34; fork&#34;流但是共享它的值(然后组合分叉的流)。

我如何分享流的价值,但也多次订阅它?

我意识到这可能与&#34;冷&#34;的概念有关。和&#34;热&#34;观测。但是:

  • Rx.Observable.just()创建的流是冷还是热?
  • 如何确定上一个问题的答案?

2 个答案:

答案 0 :(得分:1)

  

Rx.Observable.just()创建的流是冷还是热?

冷。

  

如何确定上一个问题的答案?

我想文档是唯一的指南。

  

我如何共享流的价值,但也多次订阅它?

您正在寻找a connectable observable的想法。例如:

var log = function(x) { console.log(x); };
var coldShare = Rx.Observable
  .just({ foo: 'cold share' })
  .publish();

coldShare.subscribe(log); // Does nothing
coldShare.subscribe(log); // Does nothing
coldShare.subscribe(log); // Does nothing

coldShare.connect(); // Emits one value to its three subscribers (logs three times)

var log = function(x) {
  document.write(JSON.stringify(x));
  document.write("<br>");
};

var coldShare = Rx.Observable
  .just({ foo: 'cold share' })
  .publish();

coldShare.subscribe(log); // <-- Only logs once
coldShare.subscribe(log);
coldShare.subscribe(log);

coldShare.connect();
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/4.0.7/rx.all.min.js"></script>

以上示例记录了三次。使用publishconnect,您实际上会“暂停”可观察量,直到调用connect

另见:

答案 1 :(得分:0)

我不明白你的第一个问题,但关于最后一个问题,因为我也遇到了问题:

  • Observables / Observers的Rxjs实现基于观察者模式,类似于旧的回调机制。
  • 举例来说,这是创建一个observable的基本形式(摘自https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/create.md上的文档)

    var source = Rx.Observable.create(function (observer) {
        observer.onNext(42);
        observer.onCompleted();
    
        // Note that this is optional, you do not have to return this if you require no cleanup
        return function () {
            console.log('disposed');
        };
    });
    
  • Rx.Observable.create将一个函数(比如factory_fn作为原始参数)作为参数,它接受一个观察者。您的值是通过计算factory_fn主体中的选择而生成的,并且因为您在参数中有观察者,所以您可以在看到合适时处理/推送生成的值。但是factory_fn没有被执行,它只是被注册(就像回调一样)。每当相关的observable(即subscribe(observer)返回的Rx.Observable.create(factory_fn)上有factory_fn时,就会调用它。

  • 一旦完成订阅(调用创建回调),值将根据工厂函数中的逻辑流向您的观察者,并且它将保持这种状态,直到您的observable完成或观察者取消订阅(假设您确实实现了取消值流的操作)作为Rx.Observable)的返回值。
  • 这基本上意味着默认情况下,Rx.fromEvent很冷。
  • 在使用了相当多的库之后我得出的结论是,除非有适当的记录,否则了解可观察温度的唯一方法就是关注源代码。或者在某处添加副作用,订阅两次,看看副作用是发生两次还是只发生一次(这就是你所做的)。那,或者询问stackoverflow。
  • 例如,return new EventObservable(element, eventName, selector).publish().refCount();生成热观察,如您可以从代码中的最后一行(publish)看到的那样。 (代码在这里:https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/fromevent.js)。 Rx.DOM.fromWebSocket运算符属于那些将冷可观察变为热点的运算符。它是如何工作的超出范围所以我不打算在这里详细说明。
  • 但是Rx.Observable不会产生热的可观察量(https://github.com/Reactive-Extensions/RxJS-DOM/blob/master/src/dom/websocket.js)。参看How to buffer stream using fromWebSocket Subject
  • 经常出现混乱我认为我们将实际来源(例如按钮点击流)与其表示(Rx.Observable)混为一谈。不幸的是,当发生这种情况时,我们想象的热源最终可能会被感冒Rx.Observable.just所代表。

所以,是的,{{1}}创造了冷可观察性。