Rxjava - 连锁可观察者

问题描述 投票:0回答:1

请看这段代码:

 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,如果它成功,调用getUserDetailsauthLogin调用结果中的某些字段是必需的),如果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

java observable rx-java2 flatmap
1个回答
0
投票

是的,你可以,并且应该使用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);
   }
}

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.