请看这段代码:
Disposable disposable = mcityService.authLogin(request,Utils.prepareHeaders())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(resp ->
{
mCompositeDisposable.add(mcityService.getUserDetails(selectedCity.id,Utils.prepareHeaders(resp.tokenType,resp.accessToken))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(userDetails ->
{
/*process resp and user details*/
}));
}, throwable ->
{
process errors
});
mCompositeDisposable.add(disposable);
}
所以基本上我需要调用authLogin
,如果它成功,调用getUserDetails
(authLogin
调用结果中的某些字段是必需的),如果getUserDetails
成功,链完成,我需要一些额外的处理结果来自两个调用。如果authLogin
失败或getUserDetails
失败,则应执行错误处理(例如,从throwable获取http错误代码或消息)。
由于我的方法有效,我知道这不是goot方法,如何优化它?我可以使用flatMap
运算符代替嵌套的observables吗?
编辑:方法声明:
public static Map<String, String> prepareHeaders(String tokenType, String accessToken);
Observable<UserDetails> getUserDetails(@Path(value = "cityId", encoded = true) String cityId, @HeaderMap Map<String, String> headers);
最后的尝试:
mcityService.authLogin(request, Utils.prepareHeaders())
.concatMap(response ->
{
final Map<String, String> headers = Utils.prepareHeaders(response.tokenType,response.accessToken);
return mcityService.getUserDetails(selectedCity.id, headers)
.map(userDetails -> new Object()
{
public AuthResponse ar = response;
public UserDetails ud = userDetails;
});
})
.doOnNext(responseDetails ->
{
AuthResponse ar = responseDetails.ar;
UserDetails ud = responseDetails.ud;
})
.doOnError(throwable ->
{
final String message = throwable.getMessage();
});
结果:.doOnNext
从未调用过,mcityService.getUserDetails
似乎从未被调用过,.doOnError
也从未调用过(因此没有错误)。第一次mcityService.authLogin
呼叫返回Observable<AuthResponse>
不是我真的需要subscribe
?
是的,你可以,并且应该使用flatMap
/ concatMap
/ switchMap
。
对不起,如果编码不好,我主要使用RxJS,它有pipable运算符(好多了!)。
mcityService.authLogin(request, Utils.prepareHeaders())
.concatMap(response -> {
final Map<String, String> headers = Utils.prepareHeaders(resp.tokenType,resp.accessToken);
return mcityService.getUserDetails(selectedCity.id, headers)
.map(userDetails -> ResponseUserDetails.of(response, userDetails));
})
.doOnNext(responseDetails -> {
// Hanlde ResponseUserDetails object
})
.doOnError(throwable -> {
// Handle exception
final String message = throwable.getMessage();
...
})
.subscribe(
responseDetails -> { ... },
throwable -> { ... }
);
如果您不想使用其他课程,可以动态创建Object
return mcityService.getUserDetails(selectedCity.id, headers)
.map(userDetails -> new Object() {
public Response r = response;
public UserDetails ud = userDetails;
});
并通过访问其字段
.doOnNext(responseDetails -> {
final Response r = responseDetails.r;
final UserDetails ud = responseDetails.ud;
...
})
static class ResponseUserDetails {
final Response response;
final UserDetails userDetails;
ResponseUserDetails(
final Response response,
final UserDetails userDetails) {
this.response = response;
this.userDetails = userDetails;
}
static ResponseUserDetails of(
final Response response,
final UserDetails userDetails) {
return new ResponseUserDetails(response, userDetails);
}
}