回顾 RxJava 中的链

Looking back in the chain in RxJava

Random rand = new Random();
Observable<Integer> random1 = Observable.just(rand.nextInt());
Observable<Integer> random2 = random1.flatMap(r1->Observable.just(r1 * rand.nextInt()));
random2.subscribe(System.out::println);

上面的代码只是取几个随机数,将它们相乘,然后打印输出。

这是我的问题:在我打印出结果时,有没有一种优雅的方法可以让我获得第一个随机值?请注意,我的实际系统正在进行异步调用,而不仅仅是生成随机数。

以下是一些我认为不优雅的示例:

Random rand = new Random();
Observable<Integer> random1 = Observable.just(rand.nextInt());
random1.subscribe(r1->{
  Observable<Integer> random2 = Observable.just(r1 * rand.nextInt());
  random2.subscribe(r2->{
    System.out.println(r1);
    System.out.println(r2);
  });
});

.

Random rand = new Random();
Observable<Integer> random1 = Observable.just(rand.nextInt());
Observable<int[]> result = random1.flatMap(r1->{
  int[] pair = new int[2];
  pair[0] = r1;
  pair[1] = r1 * rand.nextInt();
  return Observable.just(pair);
});
result.subscribe(pair-> {
  System.out.println(pair[0]);
  System.out.println(pair[1]);
});

.

Random rand = new Random();
int[] hack = new int[1];
Observable<Integer> random1 = Observable.just(rand.nextInt()).doOnNext(r1->hack[0]=r1);
Observable<Integer> random2 = random1.flatMap(r1->Observable.just(r1 * rand.nextInt()));
random2.subscribe(r2->{
  System.out.println(hack[0]);
  System.out.println(r2);
});

最后,我不确定这是不是一个好习惯:

Random rand = new Random();
Observable<Integer> random1 = Observable.just(rand.nextInt());
Observable<Integer> random2 = random1.flatMap(r1->Observable.just(r1 * rand.nextInt()));
random2.subscribe(r2-> System.out.println(random1.toBlocking().first()));

简答:没有。

您最干净的选择可能是构建一个 class 到 "wrap" 您的输入并将其沿链传递(或使用某种元组 class)。

你的第三个例子,你传递的 int[] 对是最接近的:

Random rand = new Random();
Observable.just(rand.nextInt())
  .flatMap(r1->{
    int[] pair = new int[2];
    pair[0] = r1;
    pair[1] = r1 * rand.nextInt();
    return Observable.just(pair);
  })
  .subscribe(pair-> {
    System.out.println(pair[0]);
    System.out.println(pair[1]);
  });

类似,值得一看 - 它似乎表明您的第一种方法(嵌套可观察对象以获得对外部可观察对象输入的访问权限)是最好的。不过,如果您关心的链上有不止一层,这可能会导致相当深的嵌套。

zip 运算符怎么样?

Random rand = new Random();
Observable<Integer> random1 = Observable.just(rand.nextInt());
Observable<Integer> random2 = Observable.just(rand.nextInt());

random1.zipWith(random2, Pair::new).subscribe(System.out::println);

有一个 flatMap 重载可以让你指定一个 Func2 来接收源值和来自 Observable 的每个值被压平:

Random rand = new Random();
Observable<Integer> random1 = Observable.just(rand.nextInt());
Observable<List<Integer>> random2 = random1.flatMap(
    r1 -> Observable.just(r1 * rand.nextInt()),
    (r1, r2) -> Arrays.asList(r1, r2));

random2.subscribe(System.out::println);