简体   繁体   English

RXJava2:链式改造请求的正确模式

[英]RXJava2: correct pattern to chain retrofit requests

I am relatively new to RXJava in general (really only started using it with RXJava2), and most documentation I can find tends to be RXJava1; 我对RXJava一般来说相对较新(实际上只开始使用它与RXJava2),我发现的大多数文档往往是RXJava1; I can usually translate between both now, but the entire Reactive stuff is so big, that it's an overwhelming API with good documentation (when you can find it). 我现在通常可以在两者之间进行转换,但整个Reactive的东西都很大,它是一个压倒性的API,有很好的文档(当你能找到它时)。 I'm trying to streamline my code, an I want to do it with baby steps. 我正在尝试简化我的代码,我想用婴儿步骤来做。 The first problem I want to solve is this common pattern I do a lot in my current project: 我想要解决的第一个问题是我在当前项目中做了很多常见的模式:

You have a Request that, if successful, you will use to make a second request. 您有一个请求,如果成功,您将用于发出第二个请求。

If either fails, you need to be able to identify which one failed. 如果其中一个失败,您需要能够识别哪个失败。 (mostly to display custom UI alerts). (主要是显示自定义UI警报)。

This is how I usually do it right now: 这就是我现在通常这样做的方式:

(omitted the .subscribeOn/observeOn for simplicity) (为简单起见,省略了.subscribeOn/observeOn

Single<FirstResponse> first = retrofitService.getSomething();

first
   .subscribeWith(
     new DisposableSingleObserver<FirstResponse>() {
         @Override
         public void onSuccess(final FirstResponse firstResponse) {

               // If FirstResponse is OK…
                Single<SecondResponse> second = 
                 retrofitService
                    .getSecondResponse(firstResponse.id) //value from 1st
                    .subscribeWith(
                      new DisposableSingleObserver<SecondResponse>() {

                           @Override
                           public void onSuccess(final SecondResponse secondResponse) {
                              // we're done with both!
                           }

                           @Override
                            public void onError(final Throwable error) {
                            //2nd request Failed, 
                            }                        
                     });

         }

         @Override
         public void onError(final Throwable error) {
              //firstRequest Failed, 
         }
      });

Is there a better way to deal with this in RXJava2? 在RXJava2中有更好的方法来处理这个问题吗?

I've tried flatMap and variations and even a Single.zip or similar, but I'm not sure what the easiest and most common pattern is to deal with this. 我已经尝试过flatMap和变体甚至是Single.zip或类似的东西,但我不确定最简单和最常见的模式是什么来处理这个问题。

In case you're wondering FirstRequest will fetch an actual Token I need in the SecondRequest. 如果您想知道FirstRequest将在SecondRequest中获取我需要的实际Token Can't make second request without the token. 没有令牌,无法发出第二个请求。

I would suggest using flat map (And retrolambda if that is an option). 我建议使用平面地图(如果这是一个选项,还可以使用retrolambda )。 Also you do not need to keep the return value (eg Single<FirstResponse> first ) if you are not doing anything with it. 如果你没有对它做任何事情,你也不需要保留返回值(例如Single<FirstResponse> first )。

retrofitService.getSomething()
    .flatMap(firstResponse -> retrofitService.getSecondResponse(firstResponse.id)
    .subscribeWith(new DisposableSingleObserver<SecondResponse>() {
         @Override
         public void onSuccess(final SecondResponse secondResponse) {
            // we're done with both!
         }

         @Override
          public void onError(final Throwable error) {
             // a request request Failed, 
          }                        
   });

This article helped me think through styles in how I structure RxJava in general. 文章让我觉得通过我如何总体结构RxJava风格。 You want your chain to be a list of high level actions if possible so it can be read as a sequence of actions/transformations. 如果可能,您希望链是一个高级操作列表,因此可以将其读作一系列操作/转换。

EDIT Without lambdas you can just use a Func1 for your flatMap. 编辑没有lambdas你可以使用Func1作为你的flatMap。 Does the same thing just a lot more boiler-plate code. 同样的事情只是更多的锅炉板代码。

retrofitService.getSomething()
    .flatMap(new Func1<FirstResponse, Observable<SecondResponse> {
        public void Observable<SecondResponse> call(FirstResponse firstResponse) {
            return retrofitService.getSecondResponse(firstResponse.id)
        }
    })
    .subscribeWith(new DisposableSingleObserver<SecondResponse>() {
         @Override
         public void onSuccess(final SecondResponse secondResponse) {
            // we're done with both!
         }

         @Override
          public void onError(final Throwable error) {
             // a request request Failed, 
          }                        
   }); 

Does this not work for you? 这不适合你吗?

retrofitService
.getSomething()
.flatMap(firstResponse -> retrofitService.getSecondResponse(firstResponse.id))
.doOnNext(secondResponse -> {/* both requests succeeded */})
/* do more stuff with the response, or just subscribe */

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM