递归地将Rx单曲组合成Observable

时间:2017-06-14 04:59:22

标签: rx-java kotlin reactive-programming

我们说我有一个名为Single的{​​{1}}可以从s_0类型中发出元素t_0或者失败(这将是T 1}}在某些语言中)。那就是:

Single<T>

s_0: -- t_0 // Success OR s_0: -- X // Failure 类型的实例使用T方法返回next()类型的Single Kotlin <中的T /强>)。此行为导致一系列Single<T>?个实例能够发出Single个实例链,其中每个T个实例可以发出一个能够返回下一个s_i的元素t_i { {1}},它会发出一个元素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 获取Observable o能够从链接开始的所有元素T在链条上没有单打时成功完成,或者如果任何一个单一失败则失败:

s_0

优雅,我的意思是这么简单(在 Kotlin 中):

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

OR

o: -- t_0 -- t_1 -- t_2 -- ... --X              // Failure

这适用于什么?

在使用带分页的REST API时可以找到此方案,其中// 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>? } 个实例可用于检索单个页面,而这些页面又可以提供能够发出后续页面的Single个实例。

2 个答案:

答案 0 :(得分:5)

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

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

获得&#34;递归的关键&#34; chaining是concatWith运算符,递归调用chain方法

答案 1 :(得分:2)

public class Q44535765 {
  public static void main(String[] args) {
    Maybe<Element> first = get();
    first.toObservable()
        .compose(o -> chain(o))
        .doOnError(e -> System.out.println(e))
        .subscribe(
            e -> System.out.println(e),
            e -> System.out.println("fail"),
            () -> System.out.println("complete"));
  }

  static Maybe<Element> get() {
    return Maybe.just(
        () -> If.<Maybe<Element>> that(Math.random() > 0.1)
            .tobe(() -> get())
            .orbe(() -> If.<Maybe<Element>> that(Math.random() > 0.5)
                .tobe(() -> Maybe.empty())
                .orbe(() -> null)
                .result())
            .result());
  }

  static Observable<Element> chain(Observable<Element> s) {
    return s.concatMap(
        e -> Observable.just(e)
            .concatWith(e.next()
                .toObservable()
                .compose(o -> chain(o))));
  }

  interface Element {
    Maybe<Element> next();
  }
}

虽然If是我的util类,但您可以改为if...else...