如何使用超时简化rxjava流

时间:2016-10-25 10:29:54

标签: java rx-java

我有以下代码段:

Observable.just(1)
    .flatMap(-> doSomething1)
    .timeout(10, SECONDS)
    .flatMap(-> doSomething2)
    .timeout(10, SECONDS)
    .flatMap(-> doSomething3)
    .timeout(10, SECONDS)
    .flatMap(-> doSomething4)
    .timeout(10, SECONDS)
    .subscribe();

每次flatMap添加timeout后,我都不想重复自己。我的第一个想法是仅将timeout应用于流的开头或结尾,但这不是我想要的行为,因为它只对更近的可观察值应用超时。

Observable.just(1)
    .flatMap(-> doSomething1)
    .flatMap(-> doSomething2)
    .flatMap(-> doSomething3)
    .flatMap(-> doSomething4)
    .timeout(10, SECONDS)
    .subscribe();

Observable.just(1)
    .timeout(10, SECONDS)
    .flatMap(-> doSomething1)
    .flatMap(-> doSomething2)
    .flatMap(-> doSomething3)
    .flatMap(-> doSomething4)
    .subscribe();

doSomethingX函数在调用时会执行一些代码,这可能需要一段时间才能返回下一个不需要被包装到超时中的observable。

如何改进?

更新:

以下更实用的例子。 ideia是组成一个流,我可以在失败或超时的情况下重试。我正在模拟其中一个运算符超时一次的情况,但是正在重试。

@Test
public void streamToBeSimplified() throws Exception {
    final AtomicBoolean retry = new AtomicBoolean(true);

    Action1<Object> print = new Action1<Object>() {
        @Override
        public void call(Object o) {
            System.out.println(" >>>" + o);
        }
    };

    Observable.just(1)
            .doOnNext(print)
            .flatMap(new Func1<Integer, Observable<Integer>>() {
                @Override
                public Observable<Integer> call(Integer integer) {
                    return Observable.just(2);
                }
            })
            .timeout(1, TimeUnit.SECONDS)
            .doOnNext(print)
            .flatMap(new Func1<Object, Observable<Integer>>() {
                @Override
                public Observable<Integer> call(Object o) {

                    if(retry.getAndSet(false)) {
                        try {
                            Thread.sleep(2000L);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    return Observable.just(3);
                }
            })
            .timeout(1, TimeUnit.SECONDS)
            .doOnNext(print)
            .retry(2)
            .subscribe();

}

1 个答案:

答案 0 :(得分:2)

您可以创建一个这样的辅助方法:

private Observable doThings() {
    return Observable.just(1)
        .flatMap(__ -> withTimeout(doSomething1, 10, TimeUnit.SECONDS))
        .flatMap(__ -> withTimeout(doSomething2, 10, TimeUnit.SECONDS));
        // etc
}

private static <T> Observable<T> withTimeout(Observable<T> observable, long time, TimeUnit timeUnit) {
    return observable
            .timeout(time, timeUnit);
}