Rx java 为什么rxjava2共享运营商不是多播?
当我的所有订户在进入下一个发射之前接收到相同的发射时,就会发生多播。但是当我使用share命令时,我没有看到多播。我有一个昂贵的手术,我只想做一次。让我们看看这段代码:Rx java 为什么rxjava2共享运营商不是多播?,rx-java,rx-java2,Rx Java,Rx Java2,当我的所有订户在进入下一个发射之前接收到相同的发射时,就会发生多播。但是当我使用share命令时,我没有看到多播。我有一个昂贵的手术,我只想做一次。让我们看看这段代码: var ob1 = Observable.fromArray(1,2,3,4,5).map { println("expensive operation") it * 2 } fun doMultiplyBy2(){ ob1.flatMap { Observable.
var ob1 = Observable.fromArray(1,2,3,4,5).map {
println("expensive operation")
it * 2
}
fun doMultiplyBy2(){
ob1.flatMap { Observable.just(" 1st subscriber: $it;") }.subscribe{println(it)}
ob1.flatMap { Observable.just(" 2nd subscriber: $it;") }.subscribe{println(it)}
ob1.share()
}
}
以下是实际输出:
expensive operation
1st subscriber: 2;
expensive operation
1st subscriber: 4;
expensive operation
1st subscriber: 6;
expensive operation
1st subscriber: 8;
expensive operation
1st subscriber: 10;
expensive operation
2nd subscriber: 2;
expensive operation
2nd subscriber: 4;
expensive operation
2nd subscriber: 6;
expensive operation
2nd subscriber: 8;
expensive operation
2nd subscriber: 10;
但为什么它在向所有订户发送之前重复昂贵的操作呢。对每个用户重复昂贵的操作?我正在使用share,因此我希望输出如下:
expensive operation
1st subscriber: 2;
2nd subscriber: 2;
expensive operation
1st subscriber: 4;
2nd subscriber: 4;
expensive operation
1st subscriber: 6;
2nd subscriber: 6;
expensive operation
1st subscriber: 8;
2nd subscriber: 8;
expensive operation
1st subscriber: 10;
2nd subscriber: 10;
有趣的是,我发现只有在执行以下操作时,才会出现预期的输出:
var ob1 = Observable.fromArray(1,2,3,4,5).map {
println("expensive operation")
it * 2
}.publish()
fun doMultiplyBy2(){
ob1.flatMap { Observable.just(" 1st subscriber: $it;") }.subscribe{println(it)}
ob1.flatMap { Observable.just(" 2nd subscriber: $it;") }.subscribe{println(it)}
ob1.connect()
}
}
从而使其成为可连接的可观察对象,然后手动连接。为什么共享不起作用
更新:我想明确问题所在:
共享应该与publish().refCount()相同,我还以为共享会为我多播,但我看不到它会这样做。让我们看一看不是使用共享而是手动使用发布和连接:
var ob1 = Observable.fromArray(1,2,3,4,5).map {
println("expensive operation")
it * 2
}.publish()
fun doMultiplyBy2(){
//ob1 = ob1.share()
ob1.flatMap { Observable.just(" 1st subscriber: $it;") }.subscribe{println(it)}
ob1.flatMap { Observable.just(" 2nd subscriber: $it;") }.subscribe{println(it)}
ob1.connect()
}
}
其输出为:
expensive operation
1st subscriber: 2;
2nd subscriber: 2;
expensive operation
1st subscriber: 4;
2nd subscriber: 4;
expensive operation
1st subscriber: 6;
2nd subscriber: 6;
expensive operation
1st subscriber: 8;
2nd subscriber: 8;
expensive operation
1st subscriber: 10;
2nd subscriber: 10;
这正是我想要的。每次排放一次的昂贵操作
不允许将其更改为使用共享:
var ob1 = Observable.fromArray(1,2,3,4,5).map {
println("expensive operation")
it * 2
}.publish().refCount()//or can use share()
fun doMultiplyBy2(){
ob1.flatMap { Observable.just(" 1st subscriber: $it;") }.subscribe{println(it)}
ob1.flatMap { Observable.just(" 2nd subscriber: $it;") }.subscribe{println(it)}
}
}
这将产生以下输出:
expensive operation
1st subscriber: 2;
expensive operation
1st subscriber: 4;
expensive operation
1st subscriber: 6;
expensive operation
1st subscriber: 8;
expensive operation
1st subscriber: 10;
expensive operation
2nd subscriber: 2;
expensive operation
2nd subscriber: 4;
expensive operation
2nd subscriber: 6;
expensive operation
2nd subscriber: 8;
expensive operation
2nd subscriber: 10;
如果publish().refCount()不像普通的可观察对象那样进行多播,那么它的目的是什么呢。它或共享有什么意义呢???正如您所知
share
操作符是相同的publish().refCount()
Refcount
使成为可连接的观察者
。所以你的代码是正确的。但是您缺少的是线程
。我想你能理解我想解释的内容。如果不让我知道
像这样更改代码
val ob1 = Observable.fromArray(1,2,3,4,5).map {
println("expensive operation")
it * 2
}.subscribeOn(Schedulers.computation()).share()
// Add subscribeOn operator to change emitting thread from MAIN to WORK
fun doMultiplyBy2() {
ob1.flatMap { Observable.just(" 1st subscriber: $it;") }.subscribe{println(it)}
ob1.flatMap { Observable.just(" 2nd subscriber: $it;") }.subscribe{println(it)}
}
doMultiplyBy2()
Thread.sleep(1000) // Waiting for ending to execute
输出
expensive operation
1st subscriber: 2;
2nd subscriber: 2;
expensive operation
1st subscriber: 4;
2nd subscriber: 4;
expensive operation
1st subscriber: 6;
2nd subscriber: 6;
expensive operation
1st subscriber: 8;
2nd subscriber: 8;
expensive operation
1st subscriber: 10;
2nd subscriber: 10;
refCount()
相当于refCount(1)
,这意味着当一个订户订阅时,可观察对象将开始执行
在下面的例子中:
var ob1=obobobable.fromArray(1,2,3,4,5).map{
println(“昂贵的操作”)
它是*2
}
.publish().refCount(1)//或.share()或.publish().refCount()
ob1.flatMap{Observable.just(“第一个订户:$it;”)}
.订阅{println(it)}
ob1.flatMap{Observable.just(“第二个订户:$it;”)}
.订阅{println(it)}
情况就是这样:
Observable has 0 subscribers
Subscriber 1 subscribes
Observable has 1 subscriber; refCount(1) condition is satisfied
Observable EXECUTES EXPENSIVE OPERATION
Subscriber 1 executes onNext()
Subscriber 1 executes onComplete() and unsubscribe
Observable has 0 subscribers
Subscriber 2 subscribes
Observable has 1 subscriber; refCount(1) condition is satisfied
Observable EXECUTES EXPENSIVE OPERATION
Subscriber 2 executes onNext()
Subscriber 2 executes onComplete() and unsubscribe
Observable has 0 subscribers
Observable has 0 subscribers
Subscriber 1 subscribes
Observable has 1 subscriber
Subscriber 2 subscribes
Observable has 2 subscribers; refCount(2) condition is satisfied
Observable EXECUTES EXPENSIVE OPERATION
Subscriber 1 executes onNext()
Subscriber 2 executes onNext()
Subscriber 1 executes onComplete() and unsubscribe
Observable has 1 subscriber
Subscriber 2 executes onComplete() and unsubscribe
Observable has 0 subscribers
如果希望可观察对象等待有2个订户,则必须增加到refCount(2)
在下面的例子中:
var ob1=obobobable.fromArray(1,2,3,4,5).map{
println(“昂贵的操作”)
它是*2
}
.publish().refCount(2)//.share()
是一个运算符,它获取一个可观察对象并返回一个新对象。您订阅了两次非共享的可观察对象,创建并丢弃了共享的可观察对象。如果共享返回了一个新的可观察对象,那么为什么这对我不起作用:var ob1=obable.fromArray(1,2,3,4,5).map{println(“昂贵的操作”)it*2}.share()fun doMultiplyBy2(){ob1.flatMap{observatable.just(“第一订户:$it;”)}.subscribe{println(it)}ob1.flatMap{observatable.just(“第二订户:$it;”)}.subscribe{println(it)}//ob1.connect()请不要将代码放在评论中。编辑您的问题并将其添加到结尾。如果您可以更新您的问题,这将是一个理想的选择,但只是为了让您知道。您编写的代码很可能是同步运行的-因此它的行为正确。您需要一个非同步源来查看您想要的行为。嘿,谢谢您的帮助。我更新了我的问题。希望您能帮助我了解更多。因此.share()
当运行在不同线程上的可观察对象订阅时,仅多播?是否有一个操作符总是多播,即使来自同一线程的可观察对象订阅时也是如此?