Kotlin中RxJava2 PublishSubject转Flowable后onNext无数据发射问题
问题分析与解决方案
嘿,我一眼就看出问题出在哪了——你用的PublishSubject特性刚好和你的需求不匹配!
核心问题:PublishSubject的"健忘"特性
PublishSubject的本质是只推送订阅发生之后的事件,它不会保留任何历史事件。你在代码里的执行顺序刚好踩了这个坑:
- 先生成
applicationList,立刻调用applicationsPublishSubject.onNext(applicationList)发射初始列表 - 之后才调用
getApplications()完成订阅
这就导致第一次发射的初始列表,在订阅者出现之前就已经"溜走"了,订阅者自然收不到这个事件。而你用Flowable.just(applicationList)能正常工作,是因为just会创建一个直接发射指定数据的Flowable,只要一订阅就会立刻把数据推出去,和Subject的事件推送逻辑完全不同。
完美解决方案:改用BehaviorSubject
如果你既想让新订阅者一订阅就能拿到当前最新的应用列表,又能在新增应用时推送更新,BehaviorSubject就是你的最佳选择——它会自动保留最后一次发射的事件,新订阅者订阅时会先收到这个最新事件,之后的新事件也能正常接收。
修改你的代码如下:
// 初始化时直接传入初始的应用列表作为默认值 val applicationsBehaviorSubject = BehaviorSubject.createDefault(generateApplications()) val applicationsFlowable = applicationsBehaviorSubject.toFlowable(BackpressureStrategy.LATEST)
这样你就不需要手动调用onNext发射初始列表了,createDefault已经帮你做好了。之后在新增应用的方法里,只需要更新列表再发射即可(别忘了先把新应用加到列表里!):
override fun createApplication(name: String): Single<Application> { val application = generateApplication(name) applicationList.add(application) // 建议发射列表的不可变副本,避免外部修改原列表导致流数据不一致 applicationsBehaviorSubject.onNext(applicationList.toList()) return Single.just(application) }
额外提醒
因为你用的是MutableList,如果直接发射原列表,后续对原列表的修改会影响已经推送给订阅者的数据(因为是引用传递)。所以最好像上面那样,用toList()生成一个不可变的副本再发射,保证流里的数据是固定的快照。
内容的提问来源于stack exchange,提问作者T. Roman
相关产品推荐
相关产品推荐

