一般来说,我对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
。没有令牌,无法发出第二个请求。
答案 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 */