Rxjava-链​​可观察物

时间:2019-03-22 10:06:28

标签: java observable rx-java2 flatmap

请查看以下代码:

 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失败,则应执行错误处理(例如,从httpable中获取http错误代码或消息)。

随着我的方法的发展,我知道这不是愚蠢的方法,如何对其进行优化?我可以使用flatMap运算符代替嵌套的可观察变量吗?

编辑:方法声明:

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吗?

1 个答案:

答案 0 :(得分:0)

是的,您可以并且应该使用flatMap / concatMap / switchMap
另外,很抱歉,如果编码不正确,我主要使用RxJS,它具有可操作的运算符(更好!)。

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