将无限有限流流转换为无限流 - Reactive X.

时间:2017-09-02 17:18:53

标签: rxjs rx-java reactivex reactive-streams

如何在Reactive x(理想情况下使用RxJava或RxJs中的示例)中实现这一目标?

a |-a-------------------a-----------a-----------a----
s1 |-x-x-x-x-x-x -| (subscribe)
s2                       |-x-x-x-x-x-| (subscribe)
s2                                               |-x-x-x-x-x-| (subscribe)
...
sn
S |-x-x-x-x-x-x-x-------x-x-x-x-x-x-x-------------x-x-x-x-x-x- (subsribe)

a是一个无限的事件流,它触发事件的有限流sn,每个事件都应该是无限流S的一部分,同时能够订阅每个sn stream(为了进行求和操作),但同时将流S保持为无限。

编辑:为了更具体,我提供了我在Kotlin中寻找的实现。 每隔10秒发射一个事件,该事件映射到4个事件的共享有限流。元流是flatMap - 编入正常的无限流。我使用doAfterNext来额外订阅每个有限流并打印出结果。

/** Creates a finite stream with events
 * $ch-1 - $ch-4
 */
fun createFinite(ch: Char): Observable<String> =
        Observable.interval(1, TimeUnit.SECONDS)
                .take(4)
                .map({ "$ch-$it" }).share()

fun main(args: Array<String>) {

    var ch = 'A'

    Observable.interval(10, TimeUnit.SECONDS).startWith(0)
            .map { createFinite(ch++) }
            .doAfterNext {
                it
                        .count()
                        .subscribe({ c -> println("I am done. Total event count is $c") })
            }
            .flatMap { it }
            .subscribe { println("Just received [$it] from the infinite stream ") }

    // Let main thread wait forever
    CountDownLatch(1).await()
}

然而,我不确定这是否是纯粹的RX&#39;方式。

1 个答案:

答案 0 :(得分:0)

你不清楚你想怎么做计数。如果您正在计算总数,则无需进行内部订阅:

AtomicLong counter = new AtomicLong()
Observable.interval(10, TimeUnit.SECONDS).startWith(0)
        .map { createFinite(ch++) }
        .flatMap { it }
        .doOnNext( counter.incrementAndget() )
        .subscribe { println("Just received [$it] from the infinite stream ") }

另一方面,如果您需要为每个中间可观察量提供一个计数,那么您可以在flatMap()内移动计数并打印出计数并在完成时重置它:

AtomicLong counter = new AtomicLong()
Observable.interval(10, TimeUnit.SECONDS).startWith(0)
        .map { createFinite(ch++) }
        .flatMap { it
                     .doOnNext( counter.incrementAndget()
                     .doOnCompleted( { long ctr = counter.getAndSet(0)
                                        println("I am done. Total event count is $ctr")
                                     } )
        .subscribe { println("Just received [$it] from the infinite stream ") }

这不是很有用,但这种报告往往会破坏正常的流。