rx-java - RxJava 条件 FlatMap 更清洁的方式
问题描述
我正在寻找一种更简洁的方法来创建条件flatMap()
,我已经阅读了这个,但我无法将它应用到我的代码中:
// given variables for the sake of simplicity
val stringSingle = Single.just("dog")
val isCatEat = Single.just(true)
val feedCat = Single.just(true)
// example
stringSingle
.flatMap { string ->
if (string == "cat") {
return@flatMap isCatEat()
.flatMap { isCatEat ->
if (isCatEat) { // if cat already ate, proceed immediately
Single.fromCallable { true }
} else { // if not, feed cat
feedCat()
}
}
} else {
Single.fromCallable { false }
}
}
正如你所看到的(好吧,代码非常难看,嵌套啊),feedCat()
如果猫已经吃过,我想通过首先检查它来避免调用。我无法应用compose()
功能,因为我无法重现我的状况。
解决方案
您可以使用filter
, 仅在满足谓词时才会发出。
我假设你想知道这只猫什么时候需要喂食。因此,我认为 observable 会更合适:
private val hasCatEaten = Single.just(true)
fun feedCat(animal: String): Observable<Unit> =
Observable.just(animal)
.filter { it == "cat" }
.flatMapSingle { hasCatEaten }
.filter { !it }
.map { Unit }
fun observeFeedCat() {
feedCat("cat")
.subscribeOn(schedulers.ioScheduler())
.observeOn(schedulers.mainScheduler())
.subscribeBy(onNext = { // Called when cat needs to be fed })
.addTo(disposables)
}
更新
这是一个更好的解决方案,它可以处理两种情况:
fun shouldFeed(animal: String): Single<Boolean> =
Single.fromCallable { animal }
.filter { it == "cat" }
.flatMap { Maybe.fromCallable { !hasEaten } }
.toSingle(false)
我对这段代码进行了单元测试(不是猫,猫吃过猫没吃过),所以我对这个答案非常有信心。
推荐阅读
- sql-server - SQL Server - 带有 string_agg 的索引视图
- r - 使用 read_table 读取 tidyverse 中带有引号的标题名称的文件
- google-cloud-functions - GCP 云函数何时确认发布/订阅消息?
- elasticsearch - ElasticSearch 将新的传入文档流式传输到客户端
- javascript - 7天后删除特定文件
- java - 当我使用 apache commons CLI 传递三个以上的选项时,结果显示为 NULL 第三个选项
- python - 生成新行并将它们附加到 DataFrame 的最快方法
- node.js - 当我在构建后运行我的 react 应用程序时,html 页面上没有显示任何内容。我该如何解决这个问题?
- excel - 基于Excel公式的VBA提取中间名
- python - 为什么我不能更改 python 窗口图标?