我对ConnectableObservable
的用例感到好奇,并认为从寒冷的可观测量(如数据库查询)转换昂贵的排放可能会有所帮助,并将它们作为热点发出。这样可以避免昂贵的重放,并且会将一组排放推送给所有运营商和订户。
经过一些思考实验后,我有些担心flatMaps中的自引用会引起问题。
例如,假设我通过ConnectableObservable
发出值1到10。但我flatMap()
每个值都是所有值的总和,然后减去当前值。
ConnectableObservable<Integer> source = Observable.range(1,10)
.doOnNext(System.out::println)
.publish();
source.flatMap(i -> source.reduce(0,(x,y) -> x + y).map(sum -> sum - i))
.subscribe(sum -> System.out.println("SUM - i: " + sum));
source.connect();
我希望我能得到这个输出。
1
2
3
4
5
6
7
8
9
10
SUM - i: 54
SUM - i: 53
SUM - i: 52
SUM - i: 51
SUM - i: 50
SUM - i: 49
SUM - i: 48
SUM - i: 47
SUM - i: 46
SUM - i: 45
但我得到了这个。
1
2
3
4
5
6
7
8
9
10
SUM - i: 53
SUM - i: 50
SUM - i: 46
SUM - i: 41
SUM - i: 35
SUM - i: 28
SUM - i: 20
SUM - i: 11
SUM - i: 1
SUM - i: -10
正如我所担心的那样,flatMap()
看起来需要重放值,因为它无法处理源的热顺序性质。因此,如果我使用cache()
运算符,那么一切正常,因为每个flatMap()
运算符都会重放缓存的值。
Observable<Integer> source = Observable.range(1,10)
.doOnNext(System.out::println)
.cache();
source.flatMap(i -> source.reduce(0,(x,y) -> x + y).map(sum -> sum - i))
.subscribe(sum -> System.out.println("SUM - i: " + sum));
这是我的问题:
此ConnectableObservable
进程究竟发生了什么?它看起来是确定性的,那么它是如何产生这些价值的呢?
在任何使用它的运营商中ConnectableObervable
可能对自我引用有危险吗?在这种情况下,cache()
应该是热门运营商吗?
答案 0 :(得分:2)
这个ConnectableObservable流程究竟发生了什么?它看起来是确定性的,那么它是如何产生这些价值的呢?
这种设置是非直观的,但是发生的事情是内部总和在它们各自的起始值被创建之前不存在,并且它们中的每一个在它们创建之后只看到原始序列一个元素。例如,对于1,内部总和将仅从2到10开始事件。
在使用ConnectableObervable的任何运算符中,ConnectableObervable可能对自引用有危险吗?在这种情况下,cache()应该是热门运营商吗?
问题不在于ConnectableObservable
,而是publish
对时间敏感且Subscriber
敏感:谁在那里接收事件,谁不在那里不会得到任何追溯