我有一个简单的操作,正在执行api调用,结果是Observable
,它会发出响应:
apiService.getTeam()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<Response>() {
...
});
如果几秒钟后没有发出任何物品,我想向用户提供一些反馈。我知道.timeout()
运算符,但这会应用于每个项目,因此即使发出了几个项目,在最后一个可用项目发出后几秒钟,超时也会导致错误。
如果没有发出任何项目,我只想暂停操作。有一种简单的方法可以做到这一点吗?
答案 0 :(得分:2)
有一个timeout
重载可用于超时第一个元素而不会超时其余元素:
Observable.never()
.timeout(() -> Observable.timer(1, TimeUnit.SECONDS), e -> Observable.never())
.toBlocking()
.subscribe(System.out::println, Throwable::printStackTrace);
这里,第二个参数只返回一个永远不会发出的Observable,因此后续元素不会超时。
答案 1 :(得分:0)
以下代码段可以解决您的问题:
public static void main(String[] args) {
boolean itemEmitted[] = { false };
long identifier = -1l;
Observable.interval(10, TimeUnit.SECONDS)
.mergeWith(Observable.just(identifier).delay(5, TimeUnit.SECONDS))
.map(v -> {
if (!itemEmitted[0] && v == identifier) { // item is not emitted and a timeout occurs
throw new RuntimeException("timeout");
}
itemEmitted[0] = true;
return v;
}).filter(v -> v != identifier).toBlocking()
.subscribe(v -> System.out.println(v));
}
Observable.interval
是您的来源Observable
,它会发布与Observable.just
与delay
合并的项目 - 其组合行为类似于timeout
。输出Observable
为map
,用于检查是否发出了实际项目或是否发生了超时identifier
。如果超时,则抛出Exception
。稍后输出filter
以从发出的项目列表中删除标识符。
您可以通过修改初始Observable.interval
中的值来使用此代码。