使用其他 Observable 过滤 RxJava Observable
Filter RxJava Observable with other Observable
我正在使用 RxAndroid 2.0.1 和 RxJava 2.0.6。
我有两个可观察对象:一个 returns Maybe<MyObject>
基于一些字符串 (ID)。当可选对象被 returned 时,如果对象满足某些条件,我必须调用第二个采用 MyObject 实例和 returns 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 不能被订阅直到第一个 returns MyObject
尝试使用 filter
- 现在的问题是我需要使用阻塞 get 来调用第二个可观察对象。它可能会工作,但看起来像代码味道:
objectDAO.getById(objectId)
.filter(myObject ->
otherDAO.checkCondition(myObject).blockingGet()
)
.subscribe(
myObject -> checkCondition(myObject),
throwable -> /* Fallback */,
() -> /* Fallback */
);
尝试使用 flatMap
- 第二个可观察的 returns 布尔值,而我需要 return 原始对象。因此,我需要使用 blockingGet
和 return 原始对象或 Maybe.empty()
映射代码片段
关于如何以代码 "clean" 的方式进行操作的任何建议(它更小,但仍然清楚内部发生了什么)?
你可以做的一件事:
objectDAO.getById(objectId)
.flatMapSingle(myObject -> otherDAO
.checkCondition(myObject)
.map(isTrue -> Pair.create(myObject, isTrue))
)
然后你有一个 Observable<Pair<MyObject, Boolean>>
并且可以随心所欲地继续:直接 subscribe
并检查那里的 Boolean
,通过布尔值 filter
等。
akarnokd 的 RxJava2Extensions 额外项目有一个 filterAsync
转换器(与 compose
一起使用),使用任何 Publisher<Boolean>
;)
我想出了解决方案,但没有传递布尔值对,以防有人遇到同样的问题。
比如objectDAO.getById(objectId)
returnsObservable<T>
和otherDAO.checkCondition(myObject)
returnsSingle<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 -> ...)
我正在使用 RxAndroid 2.0.1 和 RxJava 2.0.6。
我有两个可观察对象:一个 returns Maybe<MyObject>
基于一些字符串 (ID)。当可选对象被 returned 时,如果对象满足某些条件,我必须调用第二个采用 MyObject 实例和 returns 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 不能被订阅直到第一个 returns MyObject尝试使用
filter
- 现在的问题是我需要使用阻塞 get 来调用第二个可观察对象。它可能会工作,但看起来像代码味道:objectDAO.getById(objectId) .filter(myObject -> otherDAO.checkCondition(myObject).blockingGet() ) .subscribe( myObject -> checkCondition(myObject), throwable -> /* Fallback */, () -> /* Fallback */ );
尝试使用
flatMap
- 第二个可观察的 returns 布尔值,而我需要 return 原始对象。因此,我需要使用blockingGet
和 return 原始对象或Maybe.empty()
映射代码片段
关于如何以代码 "clean" 的方式进行操作的任何建议(它更小,但仍然清楚内部发生了什么)?
你可以做的一件事:
objectDAO.getById(objectId)
.flatMapSingle(myObject -> otherDAO
.checkCondition(myObject)
.map(isTrue -> Pair.create(myObject, isTrue))
)
然后你有一个 Observable<Pair<MyObject, Boolean>>
并且可以随心所欲地继续:直接 subscribe
并检查那里的 Boolean
,通过布尔值 filter
等。
akarnokd 的 RxJava2Extensions 额外项目有一个 filterAsync
转换器(与 compose
一起使用),使用任何 Publisher<Boolean>
;)
我想出了解决方案,但没有传递布尔值对,以防有人遇到同样的问题。
比如objectDAO.getById(objectId)
returnsObservable<T>
和otherDAO.checkCondition(myObject)
returnsSingle<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 -> ...)