Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 可观察到重用运算符执行_Java_Rx Java_Reactive Programming_Kotlin - Fatal编程技术网

Java 可观察到重用运算符执行

Java 可观察到重用运算符执行,java,rx-java,reactive-programming,kotlin,Java,Rx Java,Reactive Programming,Kotlin,给出以下示例(kotlin代码) 我想要实现的是,SourceObservable被映射一次,所有订阅者都会得到结果,但不会对每个订阅者执行映射操作 像这样 mapping A: 2 B: 2 在我的例子中,我有非常昂贵的计算,其中延迟和性能是至关重要的,我有一个热门的可观察源和许多订户 我们如何重用运算符执行?以及通常不同的映射操作?您可以使用它来缓存任何未来订户可观察到的源结果: val stream = subject.map { println("mapping") i

给出以下示例(kotlin代码)

我想要实现的是,SourceObservable被映射一次,所有订阅者都会得到结果,但不会对每个订阅者执行映射操作

像这样

mapping
A: 2
B: 2
在我的例子中,我有非常昂贵的计算,其中延迟和性能是至关重要的,我有一个热门的可观察源和许多订户

我们如何重用运算符执行?以及通常不同的映射操作?

您可以使用它来缓存任何未来订户可观察到的源结果:

val stream = subject.map {
    println("mapping")
    it * 2
}.cache()
如果您想要更精细地控制事物的缓存方式,那么这个问题值得研究

如果您不想缓存每个源可观测项,而只想重新发布新项,您可以使用:

给出了以下事件序列:

stream.forEach { println("A: $it") }
stream.forEach { println("B: $it") }

subject.onNext(1)

stream.forEach { println("C: $it") }
subject.onNext(2)
subject.onCompleted()
将打印:

mapping
A: 2
B: 2
mapping
A: 4
B: 4
C: 4

我找到了解决办法。为了重用管道的执行,我们必须确保只有一个订阅服务器,并且该订阅服务器将所有发射从管道末端传播到所有订阅服务器的条目。。。听起来很像这个主题

如果我们只订阅100次,我们将有100个管道从观测到的源开始,而在这种情况下,我们有一个管道,分支到它的最末端的100个微小管道

fun <T> Observable<T>.hub(): Observable<T> {
    val hub = PublishSubject.create<T>()
    this.subscribe(hub)
    return hub
}

问题解决了

哦,天哪,这真的很糟糕,我只是检查了运营商的来源,每个订阅者都执行链中的所有内容。。。缓存不符合我的要求,我不想将所有发射存储在任何地方,我只想让它计算并传播给每个人,而不是为每个人计算:(我知道这是在寻求帮助,但你能复制并修改OperatorMap(基本映射操作符)吗)所以它只调用transformer一次…我只需要看看正确的方法是什么…如果在工作流中进行任何调试,似乎我对它的工作原理有错误的理解,原始源observable有两个观察器,所以这个设计是从根开始的,我希望它有一个订阅者,而这反过来又有一个订阅者其他2…是否有其他RX框架不以这种方式工作?这是设计为这样的方式…每个订阅者都为自己执行整个链工作没有任何东西被重用…非常糟糕的设计imho,特别是考虑到RX打算我们使用纯函数和不可变数据…如果应该,为什么同样的工作适用于100个订阅者d只做一次…很好,我会接受这个答案,尽管我坚持使用我的解决方案,因为它至少会创建更少的对象,看起来不像黑客。而且你的解决方案也适用于纯java,因为你可以使用它,而不会断开链条,而我的解决方案只有在你拥有称为“扩展函数”的强大功能的情况下才能工作…谢谢你的回答:)
stream.forEach { println("A: $it") }
stream.forEach { println("B: $it") }

subject.onNext(1)

stream.forEach { println("C: $it") }
subject.onNext(2)
subject.onCompleted()
mapping
A: 2
B: 2
mapping
A: 4
B: 4
C: 4
fun <T> Observable<T>.hub(): Observable<T> {
    val hub = PublishSubject.create<T>()
    this.subscribe(hub)
    return hub
}
val subject = PublishSubject.create<Int>()

val stream = subject.map {
    println("mapping")
    it * 2
}

val hub = stream.hub()

hub.subscribe { println("A: $it") }
hub.subscribe { println("B: $it") }

subject.onNext(1)

subject.onCompleted()
mapping
A: 2
B: 2