亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在 RxJava 中使用 onErrorReturn 和 retryWhen

在 RxJava 中使用 onErrorReturn 和 retryWhen

慕尼黑8549860 2023-09-20 15:22:10
這是代碼:import io.reactivex.Observable;import io.reactivex.Observer;import org.junit.jupiter.api.Test;import java.util.concurrent.ThreadLocalRandom;import java.util.concurrent.atomic.AtomicBoolean;public class RxJavaTest {    @Test    public void onErr() {        Observable<String> values1 = new Observable<String>() {            @Override            protected void subscribeActual(Observer<? super String> observer) {                observer.onNext("New");                observer.onNext("New1");                observer.onNext("New2");                observer.onNext("New3");                observer.onNext("New4");                if (ThreadLocalRandom                            .current()                            .nextInt(10) == 5) {                    observer.onError(new Exception("don't retry..."));                } else {                    observer.onError(new IllegalArgumentException("retry..."));                }            }        };        AtomicBoolean finished = new AtomicBoolean(false);        values1                .retryWhen(throwableObservable -> throwableObservable                        .takeWhile(throwable -> {                            boolean result = (throwable instanceof IllegalArgumentException);                            if (result) {                                System.out.println("Retry on error: " + throwable);                                return result;                            }                            System.out.println("Error: " + throwable);                            return result;                        })                        .take(20))                .onErrorReturn(throwable -> "Saved the day!")                .doOnTerminate(() -> finished.set(true))                .subscribe(v -> System.out.println(v));    }}目標是僅當存在IllegalArgumentException,對于任何其他異常,立即返回(通過onErrorReturn)。上面的代碼實現了第一個目標,但第二個目標失敗了,它停止重試,但忽略了該.onErrorReturn部分。知道如何讓它發揮作用嗎?
查看完整描述

2 回答

?
慕蓋茨4494581

TA貢獻1850條經驗 獲得超11個贊

您可以將其更改retryWhen為:


                .retryWhen(throwableObservable ->

                                throwableObservable.flatMap(throwable -> {

                                    if (throwable instanceof IllegalArgumentException) {

                                        System.out.println("Retry on error: " + throwable);

                                        return Observable.just(1);

                                    } else {

                                        System.out.println("Error: " + throwable);

                                        return Observable.<Integer>error(throwable);

                                    }

                                })

                )

為了使其重試,返回哪個值并不重要retryWhen(在上面的示例中返回 1)。根據javadoc:


如果 ObservableSource 調用 onComplete 或 onError,則重試將在子訂閱上調用 onComplete 或 onError。否則,此 ObservableSource 將重新訂閱源 ObservableSource。


查看完整回答
反對 回復 2023-09-20
?
慕田峪9158850

TA貢獻1794條經驗 獲得超8個贊

作為記錄,這是我在看到古斯塔沃的答案之前使用的解決方案onErrorResumeNext:


    private Observable<String> createObservable(long delay) {

        Observable<String> values1 = new Observable<String>() {

            @Override

            protected void subscribeActual(Observer<? super String> observer) {

                observer.onNext("New");

                observer.onNext("New1");

                observer.onNext("New2");

                observer.onNext("New3");

                observer.onNext("New4");

                if (ThreadLocalRandom

                        .current()

                        .nextInt(8) == 2) {

                    observer.onError(new RuntimeException("don't retry..."));

                } else {

                    observer.onError(new IllegalArgumentException("retry..."));

                }

            }

        };

        return Observable.timer(delay, TimeUnit.SECONDS).flatMap(aLong -> values1)

                .onErrorResumeNext((Throwable throwable) -> {

                    if (throwable instanceof IllegalArgumentException) {

                        return createObservable(delay + 2);

                    } else {

                        return Observable.just("The default value");

                    }

                });

    }

這按預期工作,但我認為古斯塔沃建議的方式更容易理解。這是使用以下重寫的相同函數retryWhen:


    private Observable<String> createObservable1() {

        Observable<String> values1 = new Observable<String>() {

            @Override

            protected void subscribeActual(Observer<? super String> observer) {

                observer.onNext("New");

                observer.onNext("New1");

                observer.onNext("New2");

                observer.onNext("New3");

                observer.onNext("New4");

                if (ThreadLocalRandom

                        .current()

                        .nextInt(3) == 1) {

                    observer.onError(new RuntimeException("don't retry..."));

                } else {

                    observer.onError(new IllegalArgumentException("retry..."));

                }

            }

        };

        return values1.retryWhen(throwableObservable ->

                throwableObservable

                        .zipWith(Observable.range(1, 5), (throwable, integer) -> {

                            if (throwable instanceof IllegalArgumentException) {

                                System.out.println("Retry on error: " + throwable);

                                return integer;

                            }

                            System.out.println("No retry on error: " + throwable);

                            return -1;

                        })

                        .flatMap(integer -> {

                            if (integer > 0) {

                                System.out.println("Delay " + integer + " sec on retry...");

                                return Observable.timer(integer, TimeUnit.SECONDS);

                            }

                            System.out.println("Return immediately...");

                            return Observable.error(new Exception());

                        })

        ).onErrorReturnItem("Saved the day!");

    }

希望這可以幫助。


查看完整回答
反對 回復 2023-09-20
  • 2 回答
  • 0 關注
  • 227 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號