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

时间:2017-04-11 20:13:55

标签: java android rx-java retrofit2 rx-java2

一般来说,我对RXJava相对较新(实际上只是开始在RXJava2中使用它),我能找到的大多数文档都是RXJava1;我现在通常可以在两者之间进行转换,但整个Reactive的东西都很大,它是一个压倒性的API,有很好的文档(当你能找到它时)。我正在尝试简化我的代码,我想用婴儿步骤来做。我想要解决的第一个问题是我在当前项目中做了很多的常见模式:

您有一个请求,如果成功,您将用于发出第二个请求。

如果其中一个失败,您需要能够确定哪个失败了。 (主要用于显示自定义UI警报)。

这就是我现在通常做的事情:

(为简单起见,省略了class MyClass2 : MyProtocol { var someInt: Int = 42 /* Dummy 'MyClass2'-capturing type used to call the default implementation of 'MyProtocol', but with read and write access to 'MyClass2':s self:s 'someInt' instance. */ private class Dummy : MyProtocol { unowned let myClass2: MyClass2 init(_ myClass2: MyClass2) { self.myClass2 = myClass2 } var someInt: Int { get { return myClass2.someInt } set { myClass2.someInt = newValue } } } func someFuncWithDefaultImplementation() { // do some additional stuff ... print("In MyClass2 implementation, currently someInt = \(someInt)") // call default implementation of 'someFuncWithDefaultImplementation' // supplying 'self' to read/write access to self.someInt. Dummy(self).someFuncWithDefaultImplementation() print("Back in MyClass2:s implementation; now someInt = \(someInt)") // 0, woah, mutated in default implementation! } }

.subscribeOn/observeOn

在RXJava2中有更好的方法来解决这个问题吗?

我已尝试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, } }); 和变体,甚至是flatMap或类似的,但我不确定最简单和最常见的模式是什么来处理这个问题。

如果您想知道FirstRequest将在SecondRequest中获取我需要的实际Single.zip。没有令牌,无法发出第二个请求。

2 个答案:

答案 0 :(得分:12)

我建议使用平面地图(如果是选项,可以使用retrolambda)。 如果你没有做任何事情,你也不需要保留返回值(例如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文章帮助我思考了如何构建RxJava的样式。如果可能,您希望链是一个高级操作列表,因此可以将其视为一系列操作/转换。

修改 如果没有lambdas,您可以使用Func1作为flatMap。同样的事情只是更多的锅炉板代码。

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, 
          }                        
   }); 

答案 1 :(得分:3)

这不适合你吗?

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