Rx java RxJava(Android)-错误的中间步骤,在错误解决后重试

Rx java RxJava(Android)-错误的中间步骤,在错误解决后重试,rx-java,chaining,Rx Java,Chaining,我目前正在尝试进入RxJava 现在我有以下场景: 我必须对用户进行身份验证 为此,我需要执行以下步骤: 尝试使用本地存储的令牌对用户进行身份验证 如果身份验证失败(由于令牌过期),请尝试使用本地存储的 刷新令牌 备选方案: 关于成功: 在本地保存新获取的令牌 再次尝试验证,如果失败,则显示错误 失败时(因为刷新令牌也已过期):显示登录对话框 失败时(由于其他原因):显示错误 我已经实现了两个可观察对象,一个用于身份验证,一个用于令牌刷新。 它们返回两种不同类型的结果 我现在很难将这

我目前正在尝试进入RxJava


现在我有以下场景:
我必须对用户进行身份验证

为此,我需要执行以下步骤:

  • 尝试使用本地存储的令牌对用户进行身份验证
  • 如果身份验证失败(由于令牌过期),请尝试使用本地存储的 刷新令牌
  • 备选方案:
    • 关于成功:
    • 在本地保存新获取的令牌
    • 再次尝试验证,如果失败,则显示错误
    • 失败时(因为刷新令牌也已过期):显示登录对话框
    • 失败时(由于其他原因):显示错误

  • 我已经实现了两个可观察对象,一个用于身份验证,一个用于令牌刷新。 它们返回两种不同类型的结果


    我现在很难将这些步骤链接到上面提到的步骤中。 有人能给我一个提示吗


    或者这更像是一个单独的类来处理这个过程,而不是RxJava链(因为太复杂了)?

    我认为这可以用一个更简单的方法来完成,使用一个错误处理操作符
    onErrorResumeNext()
    ,它将控制传递给另一个可观察对象,而不是调用
    onError(),如果可观察对象遇到错误

    让我们假设你的两个观测值是:

    // Assuming authenticate returns an exception of typeA if it fails
    Observable<A> authenticate;
    // returns an exception of typeB if refresh fails
    Observable<B> refresh;
    
    //假设authenticate失败时返回typeA异常
    可观察的验证;
    //如果刷新失败,则返回类型B的异常
    可见刷新;
    
    现在,让我们使用concatMap创建另一个可观察对象

    // Probably you want to emit token from refresh observable. If not,
    // then I hope you will get the idea how it's done. 
    Observable<Object> refreshThenAuthenticate = refresh.concatMap(new Func1<A, Observable<B>>() {
            @Override
            public Observable<A> call(B b) {
                // create an authentication observable using the token
                return createAuthenticateObservable(b.getToken());
            }
    });
    // Above can be written in much simpler form if you use Java 8 lambdas.
    
    
    /* first authenticate will be executed, if it fails then control will
     * go to refreshThenAuthenticate.
     */
    authenticate
    .onErrorResumeNext(refreshThenAuthenticate)
    .subscribe(new Observer<A>() {
                @Override
                public void onCompleted() {
                   // login successful
                }
    
                @Override
                public void onError(Throwable e) {
                    // if e of typeA show login dialog
                    // else do something else
                }
    
                @Override
                public void onNext(A a) {
    
                }
            });
    
    //您可能希望从refresh observable发出令牌。如果没有,,
    //那我希望你能知道是怎么做的。
    可观察的refreshThenAuthenticate=refresh.concatMap(新的Func1(){
    @凌驾
    公共可观测呼叫(B){
    //使用令牌创建可观察的身份验证
    返回createAuthenticateObservable(b.getToken());
    }
    });
    //如果您使用Java8Lambdas,以上内容可以用更简单的形式编写。
    /*将执行第一次身份验证,如果失败,则将执行控制
    *去刷新页面。
    */
    证明…是真实的
    .onErrorResumeNext(刷新然后验证)
    .订阅(新观察员){
    @凌驾
    未完成的公共无效(){
    //登录成功
    }
    @凌驾
    公共无效申报人(可丢弃的e){
    //如果e类型为显示登录对话框
    //做点别的吧
    }
    @凌驾
    下一页(A){
    }
    });
    
    谢谢您的回答,这将指引我走向正确的方向。不幸的是,我有一个问题,即authenticate的observable有一个不同于刷新的类型(
    observable,observable
    )。现在我不能在
    onErrorResumeNext
    中使用concatted observable。有没有一种不需要改变两个观测值特征的解决方案?谢谢,
    concatMap
    让我走上了正确的轨道!