递归地将Rx单曲组合成Observable

Gab*_*uff 0 reactive-programming kotlin rx-java

假设我有一个可以从类型中发出元素或者失败的Single调用(在某些语言中会是这样).那是:s_0t_0TSingle<T>

s_0: -- t_0          // Success

OR

s_0: -- X            // Failure
Run Code Online (Sandbox Code Playgroud)

从类型实例T有一个next()返回一个可选的方法Single从式T以及(一个Single<T>?科特林).这种行为导致一系列Single实例能够发出一系列T实例,其中每个实例都s_i可以发出一个t_i能够返回下s_i+1一个单元的元素t_i+1,该元素将发出一个元素,依此类推,直到最后一个元素t_n-1不返回单个或任何一个元素为止单打失败:

s_0: -- t_0
        ?
        s_1: -- t_1
                ?
                s_2: -- t_2

                        ...

                        ?
                        s_n-1: -- t_n-1
                                  ?
                                  null

OR

s_0: -- t_0
        ?
        s_1: -- t_1
                ?
                s_2: -- t_2

                        ...

                        ?
                        s_i: -- X
Run Code Online (Sandbox Code Playgroud)

我正在寻找一种优雅的方法来获得一种能够从链条中发出所有元素的Observable o类型T,当链条s_0上没有更多的单曲时,或者如果任何一个单独失败则失败:

o: -- t_0 -- t_1 -- t_2 -- ... -- t_n-1 --o     // Success

OR

o: -- t_0 -- t_1 -- t_2 -- ... --X              // Failure
Run Code Online (Sandbox Code Playgroud)

通过优雅的,我的意思是,因为这(在简单的东西科特林):

// Get single somehow (out of the scope of this question)
val s0: Single<T> = provideSingle()

// Get observable
val o: Observable<T> = s0.chain()

// Define extension method
fun Single<T>.chain(): Observable<T> {
    /*
    Implement here
     */
}

// Element interface
interface T {
    fun next(): Single<T>?
}
Run Code Online (Sandbox Code Playgroud)

这适用于什么?

在使用带分页的REST API时可以找到此场景,其中Single实例可用于检索单个页面,这些页面又可以提供Single能够发出后续页面的实例.

Pel*_*cho 5

我没有对此进行测试,但基于我前段时间编写的解决方案,我将其转换为Kotlin的类似分页问题

fun Single<T>.chain(): Observable<T> =
    toObservable()
    .concatWith {
        it.next()?.chain()
        ?: Observable.empty()
    }
Run Code Online (Sandbox Code Playgroud)

获得"递归"链接的关键是concatWith操作符递归地调用该chain方法