我使用了Observable.create,因此我可以在某些数据可用时通知订阅者。我有点不确定在我的create方法中订阅了observable。这些嵌套订阅是否会给我带来任何问题?我并不完全熟悉使用Observable.create创建observable,所以我想确保我没有做任何不寻常的事情或滥用它。提前谢谢!
abstract class NetworkResource<ApiType, DbType> constructor(private val schedulerProvider: SchedulerProvider) {
abstract fun fetchFromApi(): Single<ApiType>
abstract fun fetchFromDb(): Observable<Optional<DbType>>
abstract fun saveToDb(apiType: ApiType?)
abstract fun shouldFetchFromApi(cache: DbType?): Boolean
fun fetch(): Observable<Optional<DbType>> {
return Observable.create<Optional<DbType>> {
val subscriber = it
fetchFromDb()
.subscribe({
subscriber.onNext(it)
if(shouldFetchFromApi(it.get())) {
fetchFromApi()
.observeOn(schedulerProvider.io())
.map {
saveToDb(it)
it
}
.observeOn(schedulerProvider.ui())
.flatMapObservable {
fetchFromDb()
}
.subscribe({
subscriber.onNext(it)
subscriber.onComplete()
})
}
else {
subscriber.onComplete()
}
})
}
}
}
答案 0 :(得分:2)
是的,这会导致问题。
首先,像这样嵌套Observable
并不是惯用的,Reactive方法的优势之一就是组成Observables
,因此只有一个干净的流。通过这种方式,你正在破坏链,最直接的结果是更难以阅读的交织代码,以及更多代码来连接通知事件,基本上就像用Observable
包装异步回调方法一样。 />
在这里,因为你已经有了反应组件,你可以简单地组成它们而不是用回调方法处理它们。
其次,由于打破链条,最严重且最直接的链接 - 取消订阅外部Observable
不会自动影响内部Observable
。同样适用于尝试添加subscribeOn()
和不同的情况,其中背压很重要,它也适用。
作曲替代方案可能是这样的:
fun fetch2(): Observable<Optional<DbType>> {
return fetchFromDb()
.flatMap {
if (shouldFetchFromApi(it.get())) {
fetchFromApi()
.observeOn(schedulerProvider.io())
.doOnSuccess { saveToDb(it) }
.observeOn(schedulerProvider.ui())
.flatMapObservable {
fetchFromDb()
}
} else {
Observable.empty()
}
}
}
如果出于某种原因,您希望在任何情况下单独发出第一个fetchFromDb()
结果,您也可以使用带有选择器的publish()
来执行此操作:
fun fetch2(): Observable<Optional<DbType>> {
return fetchFromDb()
.publish {
Observable.merge(it,
it.flatMap {
if (shouldFetchFromApi(it.get())) {
fetchFromApi()
.observeOn(schedulerProvider.io())
.doOnSuccess { saveToDb(it) }
.observeOn(schedulerProvider.ui())
.flatMapObservable {
fetchFromDb()
}
} else {
Observable.empty()
}
})
}
}