在RxJava中恢复TimeableException上的Flowable

时间:2018-05-09 07:51:10

标签: android rx-java reactive-programming rx-java2

我有像这样的可流动设置

            getFlowable()
            .timeout(5, TimeUnit.SECONDS)
            .observeOn(AndroidSchedulers.mainThread())
            .onErrorResumeNext(throwable -> {
                if(throwable instanceof TimeoutException) {
                    view.hideLoading();
                    return Flowable.just(new WorkExperience());
                }

                return Flowable.error(throwable);
            })
            .subscribe(workExperience -> {
                // do something
            }, throwable -> {
                Timber.e(throwable);
                view.hideLoading();
            }));

请注意timeoutonErrorResumeNext运营商的使用情况。我想在这里尝试继续从原始的flowable接收事件,如果忽略超时异常后超时。我不确定这是否正确,因为它似乎不起作用。超时发生后,我不再接收事件。我可以在这里使用一些指针。谢谢!

3 个答案:

答案 0 :(得分:2)

如果您想继续观察源,请不要超时。我假设你真正想要的是每5秒钟一些活着的通知,这样用户就不会认为应用程序冻结了。为此,只需合并映射到“忙”值的计时器:

getFlowable()
.mergeWith(Flowable.interval(5, TimeUnit.SECONDS).map(v -> new WorkExperience()))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
    workExperience -> {
        // do something
    }, 
    throwable -> {
        Timber.e(throwable);
        view.hideLoading();
    }
);

答案 1 :(得分:2)

您可以通过将timeout运算符和onErrorResumeNext移到另一个可流动的内容中来实现这一点:

private static Flowable<Integer> getFlowable() {
    return Flowable.range(1, 5)
        .concatMap(integer ->
            Flowable.just(integer)
                //the timer operator here is to simulate a long operation
                .concatMap(v -> Flowable.zip(Flowable.just(v), Flowable.timer(v, TimeUnit.SECONDS), (value, time) -> value))
                .timeout(3, TimeUnit.SECONDS)
                .onErrorResumeNext(throwable -> {
                    if (throwable instanceof TimeoutException) {
                        return Flowable.just(-1);
                    }

                    return Flowable.error(throwable);
                }));
}

public static void main(String args[]) {
    CountDownLatch latch = new CountDownLatch(1);

    getFlowable()
        .subscribe(workExperience -> {
            System.out.println("value = " + workExperience);
        }, throwable -> {
            throwable.printStackTrace();
        }, () -> {
            latch.countDown();
        });

    try {
        latch.await();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

答案 2 :(得分:0)

这就是我解决它的方式

        Flowable<WorkExperience> flowable = getFlowable();
        Flowable.just(1)
                .flatMap(i -> flowable)
                .timeout(5, TimeUnit.SECONDS)
                .onErrorResumeNext(throwable -> {
                    if (throwable instanceof TimeoutException) {
                        view.hideLoading();
                    }

                    return Flowable.empty();
                })
                .subscribe(i -> {
                }, Timber::e)

       flowable.subscribe(workExperience -> {
                if (!TextUtils.isEmpty(workExperience.getCompany())) {
                    view.populateExperiences(workExperience);
                }
            }, throwable -> {
                Timber.e(throwable);
                view.hideLoading();
            })