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 ...
随机推荐
- centos 安装PGSQL
centos 安装PGSQLCentOS下yum安装PostgreSQL目录 1 Configure YUM repository2 Install PGDG RPM file3 Install Po ...
- AS3从入门到放弃
工作久了,在技术上肯定有自己的一些见解.一直以来都懒得写下来,总觉得尤其写博客的时间,还不如自己学一点新东西.但不能总找这样的接口啊,于是乎开始了这篇博客. 工作了三年,有一年半的时间是在做AS3,在 ...
- SQL Server并行死锁案例解析
并行执行作为提升查询响应时间,提高用户体验的一种有效手段被大家所熟知,感兴趣的朋友可以看我以前的博客SQL Server优化技巧之SQL Server中的"MapReduce", ...
- 尝试在Mac上编译DNX
自从XRE改名为DNX至今,从来没有在Mac OS X上成功编译过DNX.一直很纳闷,难道DNX的开发人员不用Mac?今天突然明白了,DNX的开发人员真的不用Mac.而且DNX用的2个持续集成服务Ap ...
- 写给自己看的Linux运维基础(二) - Apache/MySQL. 安全设置. 定时任务
本文使用环境为CentOS 6 Apache, PHP, MySQL等常用软件均可通过yum安装包获取 yum install httpd php mysql-server # mysql: 客户端; ...
- Server Develop (九) Simple Web Server
Simple Web Server web服务器hello world!-----简单的socket通信实现. HTTP HTTP是Web浏览器与Web服务器之间通信的标准协议,HTTP指明了客户端如 ...
- spring-mvc.xml报错cvc-complex-type.2.4.c
添加 <!-- 定义请求处理映射HandlerMapping --> <bean id = "handlerMapping" class = "org. ...
- VR快速发展下,从业者如何把握机会?
美国科技博客VentureBeat周末刊登赛斯·沙赫纳(Seth Schachner)的文章,分析了在虚拟现实快速发展的情况下,业内所面临的机会,以及如何把握这些机会. 沙赫纳是资深的数字战略 ...
- Linux asyn-io for socket
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h&g ...
- atitit.web原理 理论attilax总结
atitit.web原理 理论attilax总结 1. Web3.01 2. Web的未来趋势1 3. Web语言与应用导论_百度百科.html2 4. <Web设计与编程导论(影印版)> ...