RxJava操作符之Share, Publish, Refcount
原文链接: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的更多相关文章
- RxJava操作符(09-算术/聚合操作&连接操作)
转载请标明出处: http://blog.csdn.net/xmxkf/article/details/51692493 本文出自:[openXu的博客] 目录: 算术聚合 Count Concat ...
- RxJava 操作符 on和doOn 线程切换 调度 Schedulers 线程池 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- RxJava操作符总结之过滤
RxJava操作符总结之过滤 jsut() just(T t1, T t2, T t3 ....) ,just能够传入多个同样类型的參数,并将当前參数一个接着一个的发送. Observable.jus ...
- RxJava操作符实践:8_算术和聚合操作之3_min
发射原始Observable的最小值. Min操作符操作一个发射数值的Observable并发射单个值:最小的那个值. RxJava中,min属于rxjava-math模块. min接受一个可选参数, ...
- RxJava操作符(08-条件和布尔操作)
转载请标明出处: http://blog.csdn.net/xmxkf/article/details/51671826 本文出自:[openXu的博客] 目录: All Amb Contains D ...
- RxJava操作符(07-辅助操作)
转载请标明出处: http://blog.csdn.net/xmxkf/article/details/51658445 本文出自:[openXu的博客] 目录: Delay Do Materiali ...
- RxJava操作符(06-错误处理)
转载请标明出处: http://blog.csdn.net/xmxkf/article/details/51658235 本文出自:[openXu的博客] 目录: Catch Retry 源码下载 1 ...
- RxJava操作符(05-结合操作)
转载请标明出处: http://blog.csdn.net/xmxkf/article/details/51656736 本文出自:[openXu的博客] 目录: CombineLatest Join ...
- RxJava操作符(04-过滤操作)
转载请标明出处: http://blog.csdn.net/xmxkf/article/details/51656494 本文出自:[openXu的博客] 目录: Debounce Distinct ...
随机推荐
- JAVA+HTML
1.采用轻量级 JApplet . import java.awt.*; import javax.swing.JApplet; public class test extends JApplet{ ...
- 捉BUG记(To Catch a Bug)
大约有一年整没有写一篇博客了,由于各种原(jia)因(ban)导致闲暇时间要么拿着IPad看岛国奇怪的片(dong)子(hua).要么拿着kindle看各种各样的资(xiao)料(shuo).本来想写 ...
- JS自动化
写在前面 记得当时刷笔试题的时候有了解过“前端工程化”,无非就是用自动化工具帮助开发人员完成一些小细节,提高工作效率之类的,不过当时可没想到可维护性这么远 构建项目 -> 模块化开发 -> ...
- Css3图标库
最近在研究icon font图标字库,觉得很有意思,于是找了一些比较好的在线字库.大都是开源的,而且各有特色,推荐给大家! 阿里icon font字库 http://www.iconfont.cn/ ...
- [ACM_模拟][ACM_暴力] Lazier Salesgirl [暴力 懒销售睡觉]
Description Kochiya Sanae is a lazy girl who makes and sells bread. She is an expert at bread making ...
- Atitit.dwr3 不能显示错误详细信息的解决方案,控件显示错误详细信息的解决方案 java .net php
Atitit.dwr3 不能显示错误详细信息的解决方案,控件显示错误详细信息的解决方案 java .net php 1. Keyword/subtitle 1 2. 使用dwr3的异常convert处 ...
- atitit. groupby linq的实现(1)-----linq框架选型 java .net php
atitit. groupby linq的实现(1)-----linq框架选型 java .net php 实现方式有如下 1. Dsl/ Java8 Streams AP ,对象化的查询api , ...
- atitit.RESTful服务的概览and框架选型
atitit.RESTful服务的概览and框架选型 1. REST基础概念: 1 2. URL说明: 1 3. 1 4. RESTful框架选型 2 1. spring mvc( recomm) ...
- Leetcode 290 Word Pattern STL
Leetcode 205 Isomorphic Strings的进阶版 这次是词组字符串和匹配字符串相比较是否一致 请使用map来完成模式统计 class Solution { public: boo ...
- Couldn't create temporary file to work with
Ubuntu中当你编译安装软件的时候可能会出现Couldn't create temporary file to work with,原因可能是: 1.权限问题 2.根目录下没有tmp文件夹 解决办 ...