我正在使用RxAndroid 2.0.1和RxJava 2.0.6。
我有两个observable:一个基于一些String(ID)返回Maybe<MyObject>
。返回可选对象时,我必须调用第二个接受MyObject实例的对象,如果对象满足某些条件,则返回Single<Boolean>
。然后我可以使用对象实例进行一些进一步的操作。
我目前的实施如下:
objectDAO.getById(objectId)
.subscribe(
myObject -> checkCondition(myObject),
throwable -> /* Fallback */,
() -> /* Fallback */
);
private void checkCondition(final MyObject myObject) {
otherDAO.checkCondition(myObject)
.subscribe(
isTrue -> {
if (isTrue) {
// yay! now I can do what I need with myObject instance
} else {
/* Fallback */
}
},
throwable -> /* Fallback */
);
}
现在我想知道如何简化我的代码。我的想法:
尝试使用zip
- 我不能,因为第二个Observable在第一个返回MyObject之前无法订阅
尝试使用filter
- 现在问题是我需要使用阻塞get来调用第二个observable。它可以工作,但看起来像代码味道:
objectDAO.getById(objectId)
.filter(myObject ->
otherDAO.checkCondition(myObject).blockingGet()
)
.subscribe(
myObject -> checkCondition(myObject),
throwable -> /* Fallback */,
() -> /* Fallback */
);
尝试使用flatMap
- 当我需要返回原始对象时,第二个observable返回布尔值。因此,我需要使用blockingGet
编写代码段并返回原始对象或Maybe.empty()
有任何建议如何以这样的方式进行,即代码是“干净的”(它更小,而且仍然清楚里面发生了什么)?
答案 0 :(得分:3)
你可以做的一件事:
objectDAO.getById(objectId)
.flatMapSingle(myObject -> otherDAO
.checkCondition(myObject)
.map(isTrue -> Pair.create(myObject, isTrue))
)
然后你有一个Observable<Pair<MyObject, Boolean>>
,可以直接按subscribe
进行操作,然后通过布尔值检查Boolean
那里,filter
等。
答案 1 :(得分:0)
akarnokd的RxJava2Extensions额外项目有一个filterAsync
变换器(与compose
一起使用)就可以使用任意Publisher<Boolean>
;)
答案 2 :(得分:0)
我想出了解决方案,但没有传递带有布尔值的Pairs,以防任何人遇到相同的问题。
例如,如果objectDAO.getById(objectId)
返回Observable<T>
,而otherDAO.checkCondition(myObject)
返回Single<Boolean>
,我们可以通过以下方式进行过滤:
objectDAO.getById(objectId)
.flatMap(myObject -> otherDAO
.checkCondition(myObject)
.toObservable()
.filter(Boolean::booleanValue)
.map(o -> myObject))
.flatMapSingle(obj -> ...)
不需要的对象将被解析为Observable.empty
并因此被过滤,因此只有需要的对象才能到达.flatMapSingle(obj -> ...)
基本上,可以通过稍微容易理解的结构来实现相同的目的(尽管我发现第一个在美学上更好一些):
objectDAO.getById(objectId)
.flatMap(myObject -> otherDAO
.checkCondition(myObject)
.flatMapObservable(isChecked -> isChecked ? Observable.just(myObject) : Observable.empty()))
.flatMapSingle(obj -> ...)