【译】RxJava中的事件广播

在RxJava中使用多点传播技巧是减少冗余工作的取胜之匙。

如果你想多点传播一个事件,也就是向所有的下游操作符或订阅者发送同一个事件。这在做耗时操作如网络请求等场景来讲是非常有用的。你不需要为每个订阅者做重复的网络请求,只需执行一次,然后传播响应结果即可。

这里有两种方式可以实现事件多播:

  1. 使用ConnectableObservable(通过publish()或者replay()[1]
  2. 使用Subject

ConnectableObservable或者Subject的操作符逻辑值只会被执行一次,利用这种原理就可以实现向下游Subscriber的事件广播了。

必须牢记的是:事件流以ConnectableObservable或者Subject作为多点传播的启动点,因此,这之后的逻辑会重复执行,并传播给每一个Subscriber

让我们通过以下示例,来了解它是如何发挥作用的:

Observable<String> observable = Observable.just("Event")  
    .publish()
    .autoConnect(2)
    .map(s -> {
      System.out.println("Expensive operation for " + s);
      return s;
    });

observable.subscribe(s -> System.out.println("Sub1 got: " + s));  
observable.subscribe(s -> System.out.println("Sub2 got: " + s));

// Output:
// Expensive operation for Event
// Sub1 got: Event
// Expensive operation for Event
// Sub2 got: Event

这个例子中,我们使用了ConnectableObservable,一个耗时的map()逻辑以及两个Subscribers。令人惊讶的结果是,这个耗时的map()逻辑执行了两次,尽管我们已经试图通过publish()来阻止这种现象的发生。

通过图表来更加清晰的描述:

如果你想让map()中的逻辑只发生一次,你需要把它放到调用publish()操作符之前:

Observable<String> observable = Observable.just("Event")  
    .map(s -> {
      System.out.println("Expensive operation for " + s);
      return s;
    })
    .publish()
    .autoConnect(2);

observable.subscribe(s -> System.out.println("Sub1 got: " + s));  
observable.subscribe(s -> System.out.println("Sub2 got: " + s));

// Output:
// Expensive operation for Event
// Sub1 received: Event
// Sub2 received: Event

更新后的图表如下:

我们应该从中吸取什么教训呢?如果你想通过事件广播减少冗余操作,请保证在正确的启动点上实现。

很多人都在使用Subject,我们不在这里对它品头论足。不得不说的是,它们都具有多点传播的特性,但是你要记住的是它们只会在发送事件这个启动点之后开始多点传播。也就是说,如果你在Subject的下游添加了大量耗时操作符,那么你就需要考虑在下游的某个地方添加另外的publish()


  1. share()cache()也可供选择使用,因为ConnectableObservable.share()的内置操作符就是publish().refCount(),同样地,由于具有相同的处理能力,cache()也可以通过replay().autoConnect()来重新创建。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,947评论 18 139
  • 本篇文章介主要绍RxJava中操作符是以函数作为基本单位,与响应式编程作为结合使用的,对什么是操作、操作符都有哪些...
    嘎啦果安卓兽阅读 2,890评论 0 10
  • http://blog.csdn.net/yyh352091626/article/details/5330472...
    奈何心善阅读 3,585评论 0 0
  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 11,160评论 6 13
  • 窗外雷声隆隆雨使天地连成一片。天公也记住今天是我母亲的祭日,从现当年的情景,让我记住这一天。母亲啊!您的离去是我今...
    78940fb42030阅读 102评论 0 2