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

时间:2017-02-23 16:28:18

标签: android rx-java retrofit2 rx-android

我是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 - universal:

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:
                        //
                }
            };
        };
    }

我很难将登录observable的当前observable放入customFunc。

我相信必须有一些其他的,更简单和正确的方法来做到这一点。 会很高兴任何帮助!

1 个答案:

答案 0 :(得分:4)

您可以使用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"));
                }
            }
        });

    }
}

此变换器会占用Observable Response<T> Observable,并将其转换为T compose(),根据您的策略发出错误。
然后将其与 Observable<Login> login(String l, String p) { return api.loginUser(l, p) .compose(new StatusCodeVerifierTransformer<>()) } 运算符一起使用:

Observable

现在,根据您的状态代码处理,您有一个onError会根据您所需的异常发出Observable

现在,您可以像使用retry运算符的任何 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; } }) 一样重试错误,例如:

Observable

BTW ,有些评论:

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