RxJava2发布

时间:2017-08-29 04:12:17

标签: android kotlin rx-java2

之间有什么区别
ObservableTransformer {
    Observable.merge(
        it.ofType(x).compose(transformerherex),
        it.ofType(y).compose(transformerherey)
    )
}

ObservableTransformer {
    it.publish{ shared ->
        Observable.merge(
            shared.ofType(x).compose(transformerherex),
            shared.ofType(y).compose(transformerherey)
        )
    }
}

当我使用这两个代码运行代码时,我得到了相同的结果。发布做了什么。

2 个答案:

答案 0 :(得分:13)

不同之处在于,顶级变压器将从下游订购一次订购上游两次,复制上游的任何副作用,这通常是不需要的:

Observable<Object> mixedSource = Observable.<Object>just("a", 1, "b", 2, "c", 3)
      .doOnSubscribe(s -> System.out.println("Subscribed!"));


mixedSource.compose(f ->
   Observable.merge(
      f.ofType(Integer.class).compose(g -> g.map(v -> v + 1)),
      f.ofType(String.class).compose(g -> g.map(v -> v.toUpperCase()))
   )
)
.subscribe(System.out::println);

将打印

Subscribed!
2
3
4
Subscribed!
A
B
C

此处表示的副作用是打印输出Subscribed!根据实际来源中的实际工作情况,这可能意味着两次发送电子邮件,检索两次表格的行。使用此特定示例,您可以看到即使源类型在其类型中交错,输出也会单独包含它们。

相反,publish(Function)将为每个最终订阅者建立一个源订阅,因此源上的任何副作用只发生一次。

mixedSource.publish(f ->
   Observable.merge(
      f.ofType(Integer.class).compose(g -> g.map(v -> v + 1)),
      f.ofType(String.class).compose(g -> g.map(v -> v.toUpperCase()))
   )
)
.subscribe(System.out::println);

打印

Subscribed!
A
2
B
3
C
4

因为来源订阅了一次,每个项目都被多播到了.ofType().compose()的两个“分支”。

答案 1 :(得分:1)

publish运算符会将您的Observable转换为Connectable Observable

让我们看看Connectable Observable的含义:假设你想多次订阅一个可观察的,并希望为每个订阅者提供相同的项目。您需要使用Connectable Observable

示例:

var period = TimeSpan.FromSeconds(1);
var observable = Observable.Interval(period).Publish();
observable.Connect();
observable.Subscribe(i => Console.WriteLine("first subscription : {0}", i));
Thread.Sleep(period);
observable.Subscribe(i => Console.WriteLine("second subscription : {0}", i));

<强>输出:

first subscription : 0 
first subscription : 1 
second subscription : 1 
first subscription : 2 
second subscription : 2

在这种情况下,我们很快就可以在发布第一个项目之前订阅,但仅限于第一个订阅。第二个订阅延迟订阅并错过了第一个出版物。

我们可以移动Connect()方法的调用,直到完成所有订阅。这样,即使调用Thread.Sleep,在完成两个订阅之后我们也不会真正订阅底层证书。这将按如下方式完成:

var period = TimeSpan.FromSeconds(1);
var observable = Observable.Interval(period).Publish();
observable.Subscribe(i => Console.WriteLine("first subscription : {0}", i));
Thread.Sleep(period);
observable.Subscribe(i => Console.WriteLine("second subscription : {0}", i));
observable.Connect();

<强>输出:

first subscription : 0 
second subscription : 0 
first subscription : 1 
second subscription : 1 
first subscription : 2 
second subscription : 2 

因此,使用Completable Observable,我们可以控制何时让Observable发出项目。

示例摘自:http://www.introtorx.com/Content/v1.0.10621.0/14_HotAndColdObservables.html#PublishAndConnect

修改 根据{{​​3}}中的第180张幻灯片:

发布的另一个本质是,如果任何观察者在10秒观察开始发射物品后开始观察,观察者只获得10秒后(在订阅时)发出的物品而不是所有物品。所以在各方面,我可以理解发布正用于UI事件。并且完全有意义的是,任何观察者应该只接收那些在订阅之前已执行的事件,而不是之前发生的所有事件。

希望它有所帮助。