【发布时间】:2021-03-28 13:54:43
【问题描述】:
考虑以下
class Dummy {
private fun firstStep(): Single<String> {
return Single.just("dafe")
.subscribeOn(Schedulers.io())
}
fun action1() {
firstStep()
.map {
mapStuff(it)
}
.doOnError {
println("${Thread.currentThread().name} it")
}
.doOnSuccess {
someVoidAction(it)
}
.flatMap {
return@flatMap anotherStep(it)
}
.observeOn(Schedulers.trampoline())
.subscribe( { result ->
println(result)
}, {
it.printStackTrace()
})
}
private fun mapStuff(it: String): Int {
println("mapStuff on thread ${Thread.currentThread().name}")
Thread.sleep(2000L)
return it.length
}
private fun someVoidAction(i: Int) {
println("someVoidAction on thread ${Thread.currentThread().name}")
Thread.sleep(2000L)
}
}
我能看到的唯一缺点是:
- 可读性不强 - 查看动作链,您无法立即判断“mapStuff”和“doVoidAction”实际上是长时间运行的任务,就像您如何判断“anotherStep”一样
- 理论上,人们可能希望为不同的任务使用不同的线程。例如,“mapStuff”可能需要
Schedulers.computation()而不是Schedulers.io()。然而,在实践中,Schedulers.io()在我的项目中使用了 99% 的时间。那么,我们需要关心吗? - 根据需要,在极少数情况下,我可能希望在“mapStuff”或“doVoidAction”上应用 2 秒超时和“错误恢复”逻辑。但话又说回来,它是情境性的,所以在一般情况下,可以像上面那样以非反应性方式执行“mapStuff”或“doVoidAction”,对吧?
还有其他我没有看到的问题吗?
以 RxJava 方式编写所有内容的缺点是它需要更多的工作,这取决于对 RxJava 的流利程度(或痴迷程度)。
这里的简单虚拟代码非常简单,但在现实生活中可能会变得复杂得多:
fun action2() {
firstStep()
.flatMap {
mapStuffReactive(it)
}
.flatMap {
return@flatMap doStuffReactive(it)
}
.flatMap {
return@flatMap anotherStep(it)
}
.observeOn(Schedulers.trampoline())
.subscribe( { result ->
println(result)
}, {
it.printStackTrace()
})
}
private fun doStuffReactive(i: Int): Single<Int> {
return Completable.fromAction {
println("someVoidAction $i")
}
.delay(2L, TimeUnit.SECONDS, Schedulers.io())
.andThen(Single.just(i))
}
private fun mapStuffReactive(it: String): Single<Int> {
return Single.just(it.length)
.delay(2L, TimeUnit.SECONDS, Schedulers.io())
}
【问题讨论】:
-
这些“长期运行的任务”是您在地图中添加的...它们是否包含副作用(接触 IO、DB 或服务器)或者它们只是计算密集型的?
-
是的,他们经常这样做
标签: rx-java reactive-programming rx-java2