使用RxJava计时器和超时的嵌套订阅

时间:2017-05-09 17:04:15

标签: java asynchronous timeout reactive-programming rx-java2

使用RxJava2,我正在尝试完成一些定时事件。

我有一些可能在不到一秒的时间内完成的异步事件,我想在继续执行异步操作的结果之前向用户显示一条消息至少一秒钟(并且可能会使用该事件)结果稍后)。

异步操作也可能超时,我想显示一条消息而不是继续。

我可以通过使用zip()将计时器作为第一个参数并将异步操作作为第二个运算符来实现此目的,但是如何处理下一个'?

这是我到目前为止的代码,实际上 可以正常工作 ,但我觉得创建嵌套订阅非常脏(使用just()代替异步操作,忽略订阅线程)

mStrings只是BehaviorSubject<String>

mStrings.onNext("Waiting 1 second. The result will fire at the Single.timer onComplete");
Single.zip(Single.timer(1, TimeUnit.SECONDS), Single.just("First"), (t1, t2) -> t2)
  .timeout(15, TimeUnit.SECONDS, observer -> {
      mStrings.onNext("First timeout fired");
  })
  .subscribe(s1 -> {
      mStrings.onNext("First timer fired and returned " + s1);
      Single.zip(Single.timer(1, TimeUnit.SECONDS), Single.just("Second"), (t1, t2) -> t2)
        .timeout(15, TimeUnit.SECONDS, observer -> {
            mStrings.onNext("Second timeout fired");
        })
        .subscribe(s2 -> {
            mStrings.onNext("Second timer fired and returned " + s2 + ". Previous was " + s1);
            Single.zip(Single.timer(1, TimeUnit.SECONDS), Single.just("Third"), (t1, t2) -> t2)
              .timeout(15, TimeUnit.SECONDS, observer -> {
                  mStrings.onNext("Third timeout fired");
              })
              .subscribe(s3 -> {
                  mStrings.onNext("Third timer fired and returned " + s3 + ". Previous was " + s1 + " and " + s2 );
              });
        });
  });

结果是:

17:53:53.219 Waiting 1 second. The result will fire at the Single.timer onComplete
17:53:54.220 First timer fired and returned First
17:53:55.224 Second timer fired and returned Second. Previous was First
17:53:56.224 Third timer fired and returned Third. Previous was First and Second

我是否错过了在这种类型的流程中有意义的运算符?还是一些基本的方法?我知道我可能能够使用多个科目来制定替代解决方案,但似乎过度。

1 个答案:

答案 0 :(得分:0)

我想我修复了自己的问题。 flatMap可用于将所有订阅压缩为一个,每个timertimeout仍将按预期运行。

mStrings.onNext("Waiting 1 second. The result will fire at the Single.timer onComplete");
Single.zip(Single.timer(1, TimeUnit.SECONDS), Single.just("First"), (t1, t2) -> t2)
  .timeout(2, TimeUnit.SECONDS, observer -> {
      mStrings.onNext("First timeout fired");
  })
  .flatMap(s1 -> {
      mStrings.onNext("First timer fired and returned " + s1);
      return Single.zip(Single.timer(1, TimeUnit.SECONDS), Single.just("Second"), (t1, t2) -> t2)
        .timeout(15, TimeUnit.SECONDS, observer -> {
            mStrings.onNext("Second timeout fired");
        })
        .flatMap(s2 -> {
            mStrings.onNext("Second timer fired and returned " + s2 + ". Previous was " + s1);
            return Single.zip(Single.timer(1, TimeUnit.SECONDS), Single.just("Third"), (t1, t2) -> t2)
              .timeout(15, TimeUnit.SECONDS, observer -> {
                  mStrings.onNext("Third timeout fired");
              })
              .flatMap(s3 -> {
                  mStrings.onNext("Third timer fired and returned " + s3 + ". Previous was " + s1 + " and " + s2 );
                  return Single.just("Fourth");
              });
        });
  })
  .subscribe(s -> {
      // ignored
  });
}));

通过更加逻辑地组合Observables,仍然可以简化复杂的嵌套。