【问题标题】:How to add a timeout to detect that an Observable didn't emit for a while如何添加超时以检测 Observable 有一段时间没有发出
【发布时间】:2017-03-15 09:18:29
【问题描述】:

我的用例如下:

我创建了一个 Observable 来访问远程服务器以获取一些数据。但是,由于服务器设计不善,因此永远不会有任何响应和例外。为了解决这个问题,我想要一些超时重试机制。

目前我尝试启动一个计时器来停止请求并在其中抛出异常,然后重试直到一定次数的尝试或我真正的超时。我尝试使用mergeWith 运算符将请求与映射的Observable.interval 合并以使用Observable.error() 生成错误,但是我无法在订阅者中捕获错误,而且看起来Observable.interval 永远不会结束。

对于 RXJAVA 中的任何操作符,我应该如何处理这种情况?

我当前的代码如下所示:

Observable.fromEmitter(fetchNetwork->...)
.mergeWith(Observable.interval(...)
           .flatmap(n->(observable.error)))
.retryWhen(error->(checkTimeExceed))
.subscribe(handleResult)

【问题讨论】:

  • 尝试改进问题

标签: rx-java


【解决方案1】:

您可以将timeout() 运算符与retryWhen() 一起使用:

Observable.fromEmitter(fetchNetwork->...)
     .timeout(TIMEOUT_VALUE, TimeUnit.SECONDS)
     .retryWhen(observable -> observable.flatMap(error -> {
                if (error instanceof TimeoutException) {
                    return Observable.just(new Object());
                } else {
                    return Observable.error(error);
                }
            }))
     .subscribe(handleResult)

这将在 TIMEOUT_VALUE 秒后使请求超时,并且只要请求超时就会重试,其他错误将照常传播给订阅者onError()

【讨论】:

  • 我看不到计时器是如何在某处重新启动的?
  • retryWhen 就是这样做的,超时的情况下会重新订阅,配置的超时时间
  • @yosriz 无法解析符号“fromEmitter”,我猜它已经过时了。我认为它可以是任何其他运算符,例如“just”?
  • @okset,是的,这个 api 在 RxJava 1.3 之上发生了变化,现在是 create,但是这个答案并没有专门提到这个运算符
猜你喜欢
  • 2017-06-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多