[英]Rxjava - chain observables
Please look at this code: 请看这段代码:
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);
}
So basically I need to call authLogin
, if it succedes, call getUserDetails
(some fields from authLogin
call results are required), if getUserDetails
succeded, chain is finished and I need some additional processing result from both calls. 所以基本上我需要调用authLogin
,如果成功,则调用getUserDetails
(需要来自authLogin
调用结果的某些字段),如果getUserDetails
成功,则链完成,我需要两个调用的一些额外处理结果。 If authLogin
fails or getUserDetails
fails, error processing should be performed (for example, get http error code or message from throwable). 如果authLogin
失败或getUserDetails
失败,则应执行错误处理(例如,从throwable获取http错误代码或消息)。
As my approach works, I know it's not goot approach, how to optimize it? 由于我的方法有效,我知道这不是goot方法,如何优化它? Can I use flatMap
operator instead nested observables? 我可以使用flatMap
运算符代替嵌套的observable吗?
edit: Methods declarations: 编辑:方法声明:
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);
Final attempt: 最后的尝试:
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();
});
Results: .doOnNext
never called, mcityService.getUserDetails
seems to be never called, .doOnError
also never called (so there was no error). 结果: .doOnNext
从未调用过, mcityService.getUserDetails
似乎永远不会调用, .doOnError
也从未调用过(因此没有错误)。 First mcityService.authLogin
call returns Observable<AuthResponse>
don't I really need subscribe
? 首先mcityService.authLogin
调用返回Observable<AuthResponse>
我真的不需要subscribe
吗?
Yes, you can, and should use flatMap
/ concatMap
/ switchMap
. 是的,你可以,并且应该使用flatMap
/ concatMap
/ switchMap
。
Also, sorry if it is not coded well, I primarily use RxJS, which has pipable operators (much better!). 对不起,如果编码不好,我主要使用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 -> { ... }
);
If you don't want to use an additional class, you can create an Object
on the fly 如果您不想使用其他类,则可以动态创建Object
return mcityService.getUserDetails(selectedCity.id, headers)
.map(userDetails -> new Object() {
public Response r = response;
public UserDetails ud = userDetails;
});
And access its fields via 并通过访问其字段
.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);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.