用于改造响应代码处理的自定义 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
并将其转换为 T
的 Observable
,根据您的策略发出错误。
然后将其与 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
的安全方法。
我是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
并将其转换为 T
的 Observable
,根据您的策略发出错误。
然后将其与 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
的安全方法。