RxJava 2中条件式订阅两个Observable的优化方案咨询
更优雅的RxJava 2条件订阅实现方案
你提到的嵌套订阅确实是RxJava里要尽量避免的模式,容易陷入回调地狱;而你用flatMap加Observable.empty()的写法虽然可行,但确实把过滤和转换的逻辑混在了一起,可读性不够好。这里有两种更优雅的实现方式,让你的数据流逻辑更清晰:
方案一:用filter + flatMap拆分逻辑
这个方案的核心是把条件过滤和Observable转换拆分成两个独立的操作符,让每一步的职责更明确:
fun main(args: Array<String>) { getProductDetails() // 先过滤出符合条件的ProductDetails .filter { it.productID == 1234 } // 只对符合条件的项,转换为获取销售信息的Observable .flatMap { getSalesInfo() } .subscribeBy( onNext = { saleInfo -> println(saleInfo.salesReference) } ) } fun getProductDetails(): Observable<ProductDetails> = Observable.just(ProductDetails(1234, "Product One")) fun getSalesInfo(): Observable<SaleInfo> = Observable.just(SaleInfo("Sales Reference 1")) data class ProductDetails(val productID: Int, val productDescription: String) data class SaleInfo(val salesReference: String)
为什么这个写法更好?
- 单一职责:
filter只负责判断是否满足条件,flatMap只负责转换Observable,逻辑拆分后更容易理解和维护; - 代码更简洁:不需要在
flatMap里写分支判断,数据流的走向一目了然; - 行为一致:如果
getProductDetails返回的项不满足条件,filter会直接丢弃它,后续的flatMap和订阅逻辑都不会执行,完全符合你的需求。
方案二:用flatMap结合Observable.never()(可选)
如果你偏好把逻辑放在flatMap里,也可以用Observable.never()替代Observable.empty()——它和empty()的区别是不会发送onComplete事件,如果你不希望订阅者收到完成信号,这个写法会更语义化:
getProductDetails() .flatMap { productDetails -> if (productDetails.productID == 1234) { getSalesInfo() } else { Observable.never() } } .subscribeBy { saleInfo -> println("Using flatmap ${saleInfo.salesReference}") }
不过总体来说,方案一的可读性和可维护性更高,是更推荐的做法。
内容的提问来源于stack exchange,提问作者ant2009
相关产品推荐
相关产品推荐

