原文链接:http://nerds.weddingpartyapp.com/tech/2015/01/21/rxjava-share-publish-refcount-and-all-that-jazz/

看源码知道.share()操作符是.publish().refcount()调用链的包装。

先来看ConnectedObservable

“ConnectedObservable” – This is a kind of observable which doesn’t emit items even if subscribed to.
It only starts emitting items after its .connect() method is called.

因为这个原因,在ConnectedObservable的connect这个方法被调用之前,connected obesrvable也被认为是“冷”和不活跃。

再看publish方法

.publish()– This method allows us to change an ordinary observable into a “ConnectedObservable”.
Simply call this method on an ordinary observable and it becomes a connected one.

现在我们知道了share操作符的1/2,那么为什么需要运用Connected Observable这个操作符呢?文档上是这么写的:

In this way you can wait for all intended Subscribers to subscribe to the Observable before the Observable begins emitting items.

这就意味着publish可以调用多个subscriber。当你有超过一个订阅者的时候,处理每个订阅和正确的销毁他们变得棘手。 为了使这个更方便,Rx发明了这个魔法操作符refcount():

refcount() – This operator keeps track of how many subscribers are subscribed to the resulting Observable and
refrains from disconnecting from the source ConnectedObservable until all such Observables are unsubscribed.

refcount本质上在后台维护着一个引用计数器,当一个subscription需要取消订阅或者销毁的时候,发出一个正确的动作。

我们再次看一下debouncedBuffer的例子,看一下在哪,share是怎么用的。

Observable<Object> tapEventEmitter = _rxBus.toObserverable().share();
// which is really the same as:
Observable<Object> tapEventEmitter = _rxBus.toObserverable().publish().refcount();

我们现在有了一个"shareable"的名字叫"tapEventEmitter"的observable。 因为他是可以分享的,而且还不是“live”(share操作符中的publish调用使其变成一个ConnectedObservable), 我们可以用他构成我们的Observables,而且要确保我们有了一个原始的observable的引用 (这个例子中原始的observable是_rxBus.toObserverable()).

Observable<Object> tapEventEmitter = _rxBus.toObserverable().share();
Observable<Object> debouncedEventEmitter = tapEventEmitter.debounce(1, TimeUnit.SECONDS);
tapEventEmitter.buffer(debouncedEventEmitter)
//...

所有的这一切看起来都很好。然而这个实现会有一个可能的竞争条件。因为这有两个subscribers(debounce and buffer)而且会在不同的时间点发生,所以竞争条件就会发生。 记住RxBus是由hot/live Subject支持的不断的发射数据。通过使用share操作符,我们保证引用的是同一个资源。 而不是subscribers在不同的时间点订阅,他们会收到准确的相同的数据。

The race condition is when the two consumers subscribe. Often on a hot stream it doesn’t matter when subscribers come and go,and refCount is perfect for that.
The race condition refCount protects against is having only 1 active subscription upstream. However,if 2 Subscribers subscribe to a refcounted stream that emits 1, 2, 3, 4, 5, the first may get 1, 2, 3, 4, 5 and the second may get 2, 3, 4, 5. To ensure all subscribers start at exactly the same time and get the exact same values, refCount can not be used.
Either ConnectableObservable with a manual, imperative invocation of connect needs to be done, or the variant of publish(function)which connects everything within the function before connecting the upstream.

在我们的用法中几乎立即执行所以没有什么关系。但是我们原始的意图是把debouncedBuffer方法作为一个单独的操作符。 如果相同的事件没有被发射出去,从概念上看起来是不正确的。

通过Bean后来的建议,我添加了一个更好的第三方的实现,用来处理这种竞争条件。

// don't start emitting items just yet by turning the observable to a connected one
ConnectableObservable<Object> tapEventEmitter = _rxBus.toObserverable().publish(); tapEventEmitter.publish((Func1) (stream) -> { // inside `publish`, "stream" is truly multicasted // applying the same technique for getting a debounced buffer sequence
return stream.buffer(stream.debounce(1, TimeUnit.SECONDS)); }).subscribe((Action1) (taps) {
_showTapCount(taps.size());
}); // start listening to events now
tapEventEmitter.connect();

RxJava操作符之Share, Publish, Refcount的更多相关文章

  1. RxJava操作符(09-算术/聚合操作&连接操作)

    转载请标明出处: http://blog.csdn.net/xmxkf/article/details/51692493 本文出自:[openXu的博客] 目录: 算术聚合 Count Concat ...

  2. RxJava 操作符 on和doOn 线程切换 调度 Schedulers 线程池 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  3. RxJava操作符总结之过滤

    RxJava操作符总结之过滤 jsut() just(T t1, T t2, T t3 ....) ,just能够传入多个同样类型的參数,并将当前參数一个接着一个的发送. Observable.jus ...

  4. RxJava操作符实践:8_算术和聚合操作之3_min

    发射原始Observable的最小值. Min操作符操作一个发射数值的Observable并发射单个值:最小的那个值. RxJava中,min属于rxjava-math模块. min接受一个可选参数, ...

  5. RxJava操作符(08-条件和布尔操作)

    转载请标明出处: http://blog.csdn.net/xmxkf/article/details/51671826 本文出自:[openXu的博客] 目录: All Amb Contains D ...

  6. RxJava操作符(07-辅助操作)

    转载请标明出处: http://blog.csdn.net/xmxkf/article/details/51658445 本文出自:[openXu的博客] 目录: Delay Do Materiali ...

  7. RxJava操作符(06-错误处理)

    转载请标明出处: http://blog.csdn.net/xmxkf/article/details/51658235 本文出自:[openXu的博客] 目录: Catch Retry 源码下载 1 ...

  8. RxJava操作符(05-结合操作)

    转载请标明出处: http://blog.csdn.net/xmxkf/article/details/51656736 本文出自:[openXu的博客] 目录: CombineLatest Join ...

  9. RxJava操作符(04-过滤操作)

    转载请标明出处: http://blog.csdn.net/xmxkf/article/details/51656494 本文出自:[openXu的博客] 目录: Debounce Distinct ...

随机推荐

  1. 【NetDIY智能主控】开发计划

    经过一个轮回,硬件开发.硬件创业又被推到了历史的前台. 面向低端.初级的硬件爱好者,以Arduino和81单片开发板为核心的开源硬件越来越深入人心,参与的人群越来越多,相关硬件和周边模块也越来越便宜. ...

  2. ArcServer JS API开发离线部署方法

      1. 下载ArcGIS API for JavaScript 3.6 Library. (地址:http://support.esrichina.com.cn/uploadfile/Javascr ...

  3. 团队项目--站立会议 DAY3

    小组名称:D&M 参会人员:张靖颜,钟灵毓秀,何玥,赵莹,王梓萱 今天是站立会议的第三天 在前两次会议的基础上 组员们总结了自己在任务中的经验 个抒己论在会议中进行了一些讨论 并且对接下来的工 ...

  4. [ACM_图论] Fire Net (ZOJ 1002 带障碍棋盘布炮,互不攻击最大数量)

    Suppose that we have a square city with straight streets.  A map of a city is a square board with n ...

  5. Qt之课外实践——文件操作(简单清道夫)

    说明:这个小项目是关于文件操作的.主要的功能有:重复文件的查找(根据文件的大小),说白了,就是讲大小相同的文件在一起显示出来,供用户自由的选择删除.这个360云盘里的文件去重还差的很远.还有空文件夹的 ...

  6. HTML5 ——本地存储

    目录 一.HTML4客户端存储 1.1.提交表单发送到服务器的信息 1.2.客户端本地存储概要 二.localStorage 2.1.添加 2.2.取值 2.3.修改 2.4.删除 2.5.跨页面与跨 ...

  7. intellij代码跳转后跳回

    跳转快捷键: ctrl+b 跳回的快捷键默认为 ctrl+alt+left 然而在我的电脑上并没有卵用,所以自己设置回退的快捷键,设置位置为: File/Setting/Keymap 选择 Main ...

  8. 《.NET 编程结构》专题汇总(C#)

    前言     掌握一门技术,首要的是掌握其基础.     笔者从事.NET相关开发多年,也非常喜欢.NET,多年来也积累了很多相关的资料,在此将一些基础性的知识整理成专题,分享之.   导航 基础编程 ...

  9. atitit.跨平台gui 概览

    atitit.跨平台gui 概览 为什么需要跨平台gui 国际上那些跨平台的GUI程序,除了像Firefox之类的大型项目会重写界面外,中小型的项目基本上都是用GTK+或WxWidgets为多.毕竟要 ...

  10. Spring对象绑定与类型转换

    Spring对象绑定与类型转换 Spring的框架体系中,到处充斥着对象绑定从bean的初始化autowired属性,SpringMvc 中对对象的绑定等.Spring对象绑定和类型转换在Spring ...