用于改造响应代码处理的自定义 rx Func1

Custom rx Func1 for retrofit response code handling

我是rxjava的新手,所以请不要严格...

我有下一个虱子请求:

Observable<Login>login(String l, String p){
        return api.loginUser(l,p)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .flatMap(new Func1<Response<Login>, Observable<? extends Login>>() {
                    @Override
                    public Observable<? extends Login> call(Response<Login> r) {
                        switch (r.code()){
                            case 200:
                                requestOk(r);
                                break;
                            case 202:
                                //need to Repeat
                                login.timeout(2000,TimeUnit.Milliseconds);
                                break;
                            default:
                                //
                        }
                    }
                });
    }

Observable<Login> requestOk(final Response<Login> r){
            return Observable.create(new Observable.OnSubscribe<Login>(){
                @Override
                public void call(Subscriber<? super Login> subscriber) {
                    if (subscriber.isUnsubscribed()) return;
                    subscriber.onNext(r.body());
                    subscriber.onCompleted();
                }
            });
        }

它工作正常。但是还会有很多其他请求,我需要检查请求代码以防重复。

所以我尝试创建自定义 Func1 - 对所有请求通用:

private <T>Func1<? super Response<T>, ? extends Observable<? extends T>> customFunc(final Observable<T> o) {
        return new Func1<Response<T>, Observable<? extends T>>() {
            @Override
            public Observable<? extends T> call(Response<T> r) {
                switch (r.code()){
                    case 200:
                        //
                        break;
                    case 202:
                        //need to Repeat
                        return o.timeout(2000,TimeUnit.Milliseconds);
                        break;
                    default:
                        //
                }
            };
        };
    }

我坚持将登录可观察到的当前可观察到 customFunc。

我相信一定有其他更简单、更正确的方法来做到这一点。 很高兴提供任何帮助!

您可以使用 Transformer 创建通用状态码验证器:

class StatusCodeVerifierTransformer<T> implements Observable.Transformer<Response<T>, T> {

    @Override
    public Observable<T> call(Observable<Response<T>> responseObservable) {
        return responseObservable.flatMap(new Func1<Response<T>, Observable<T>>() {
            @Override
            public Observable<T> call(Response<T> loginResponse) {
                switch (loginResponse.code()) {
                    case 200:
                        return Observable.just(loginResponse.body());
                    case 202:
                        //need to Repeat
                        return Observable.error(new Status202Exception());
                    default:
                        return Observable.error(new Exception("unknown error"));
                }
            }
        });

    }
}

此转换器将采用 Response<T> 的任何 Observable 并将其转换为 TObservable,根据您的策略发出错误。
然后将其与 compose() 运算符一起使用:

  Observable<Login> login(String l, String p) {
    return api.loginUser(l, p)
            .compose(new StatusCodeVerifierTransformer<>())
   }

现在你有一个 Observable,它将根据你的状态代码处理发出 onError 和你想要的异常。

现在,您可以像使用 retry 运算符的任何 Observable 一样重试错误,例如:

 api.loginUser(l, p)
            .compose(new StatusCodeVerifierTransformer<>())
            .retry(new Func2<Integer, Throwable, Boolean>() {
                @Override
                public Boolean call(Integer retryCount, Throwable throwable) {
                    return throwable instanceof Login202Exception && retryCount < MAX_RETRY;
                }
            })

顺便说一句,一些评论:

requestOk - 你绝对不需要创建 Observable 一次发出特定值,只需使用 just() 运算符,就像在 StatusCodeVerifierTransformer 示例中一样。 (或者对于任何其他同步操作,您有很多运算符,例如 fromCallable()just()from()
通常,create() 不再是创建 Observable 的安全方法。