编程语言
首页 > 编程语言> > android-RxJava:如何从flatMap运算符中的错误中恢复

android-RxJava:如何从flatMap运算符中的错误中恢复

作者:互联网

我有一个EditText,用户在其中输入搜索查询,当用户键入内容时,我想在服务器上执行即时搜索.

我尝试使用RxJava做到这一点,如下所示:

RxTextView.textChanges(editQuery) // I'm using RxBinding for listening to text changes
    .flatMap(new Func1<CharSequence, Observable<UserPublic[]>>() {
        @Override
        public Observable<UserPublic[]> call(CharSequence query) {
            return api.searchUsers(query); // I'm using Retrofit 1.9 for network calls. searchUsers returns an Observable<UserPublic[]>
        }
    })
    .subscribe(Observers.create(
        new Action1<UserPublic[]>() {
            @Override
            public void call(UserPublic[] userPublics) {
                processResult(userPublics);
            }
        })
        , new Action1<Throwable>() {
            @Override
            public void call(Throwable throwable) {
                processError(throwable);
            }
    });

问题是,如果网络呼叫遇到错误,整个可观察的站点将停止.因此,当用户继续输入时,什么也不会发生.

如何修改此代码,以便:

>每当出现网络问题时,都会调用processError
>但是,当用户继续输入时,新的网络调用将继续发出(再次导致processResult / processError)

解决方法:

在订阅之前,请使用retryWhen()运算符并将其附加到可观察的链上.注意,retryWhen()的参数是一个带有Observable< Throwable>的函数.并返回Observable&lt ;?>.返回的类型无关紧要,因为运算符使用onNext()结果发起重试,而onError()或onCompleted()结果终止链.

这是一个等待5秒然后重试的天真应用程序:

observable
  .retryWhen( errorObservable -> errorObservable.delay( 5, TimeUnit.SECONDS ) )
  .subscribe();

这是一个较幼稚的操作,它会在超时后重试,如果发生IOException,则会失败:

observable
  .retryWhen( errorObservable -> errorObservable.flatMap( throwable -> { // (1)
       if ( throwable instanceof IOException ) {
         return Observable.error( throwable ); // (2)
       }
       return Observable.just(1); // (3)
     } )
  .subscribe();

>使用flatMap()可以将决策推迟到知道要处理的错误类型为止.
>返回的observable抛出所提供的错误或您想要更好地描述问题的其他内容.
>提供一个简单地执行onNext()的可观察对象,告诉retryWhen()运算符重新订阅原始的可观察对象.

标签:rx-java,rx-android,android
来源: https://codeday.me/bug/20191119/2036332.html