将RxJava可观察的错误转换为另一个可观察的吞并成功

时间:2015-05-13 18:12:35

标签: retrofit reactive-programming rx-java observable

如何将可观察的错误转换为另一个可观察的错误?

我正在尝试实现以下方案中显示的算法:

Block scheme

我正在使用一个名为Grokking RxJava的教程来开始我的学习,发现flatMap运算符可以将一个Obtrable转换为另一个Obtrable转换为另一个允许我对服务器方法进行调用的链。但是在教程链接方法中总是返回成功结果。 如果其中一个远程方法返回错误,我如何进行相同的链接?

目前,我使用的方法对我来说很奇怪且不清楚:

AppObservable.bindActivity(this, userService.checklogin(mPhone)
            .onErrorResumeNext(new Func1<Throwable, Observable<? extends Response>>() {
                @Override
                public Observable<? extends Response> call(Throwable throwable) {
                    return Observable.just(null);
                }
            }))
            .flatMap(new Func1<Response, Observable<Response>>() {
                @Override
                public Observable<Response> call(Response response) {
                    if (response == null) {
                        return AppObservable.bindActivity(RegistrationActivity.this, userService.register(
                                mPhone,
                                name.getText().toString(),
                                selectedSex,
                                selectedDateDay,
                                selectedDateMonth,
                                selectedDateYear,
                                Locale.getDefault().getLanguage(),
                                persistentUserInfoStore.getInstallationToken()
                        ));
                    }
                    phone.setError(getString(R.string.already_registered_phone));
                    progressDialog.dismiss();
                    return Observable.empty();
                }
            })
            .subscribe(new Action1<Response>() {
                @Override
                public void call(Response response) {
                    startConfirmationActivity();
                    progressDialog.dismiss();
                }
            }, new Action1<Throwable>() {
                @Override
                public void call(Throwable throwable) {
                    progressDialog.dismiss();
                    Toast.makeText(RegistrationActivity.this, "Error while register user", Toast.LENGTH_SHORT).show();
                }
            });

有没有更明确的方法来做到这一点。

P.S。我是RxJava的新手。

1 个答案:

答案 0 :(得分:5)

  1. 您应该从userService.register
  2. 致电onErrorResumeNext
  3. 区分发生何种错误的最简单方法是为每个错误引入一个单独的Exception类。
  4. 这就是它在代码中的样子:

    userService.checkLogin(mPhone).flatMap(new Func1<Response, Observable<Response>() {
        @Override
        public Observable<? extends Response> call(final Response response) {
            // according to your diagram the whole Observable should fail if first call was successful
            return Observable.error(new FirstCallWasSuccessfulException(response));
        }
    }).onErrorResumeNext(new Func1<Throwable, Observable<? extends Response>>() {
        @Override
        public Observable<? extends Response> call(final Throwable throwable) {
            if (throwable instanceof FirstCallWasSuccessfulException) {
                return Observable.error(throwable);
            }
    
            return userService.register(...);
        }
    }).subscribe(new Subscriber<Response>() {
        @Override
        public void onError(final Throwable throwable) {
            if (throwable instanceof FirstCallWasSuccessfulException) {
                // foo
            } else {
                // bar
            }
        }
    
        @Override
        public void onNext(final Response response) {
    
        }
    
        @Override
        public void onCompleted() {
    
        }
    });