我的应用程序中有许多用于网络请求的Observable。由于有很多相同之处,因此我对它们进行了可观察的转换:
/**
* Creates a transformer that applies the schedulers and error handling for all of the observables in this ViewModel.
*/
private fun applyTransformations(): Observable.Transformer<NetworkState, NetworkState> {
return Observable.Transformer { observable ->
observable
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.onErrorReturn { NetworkState.Error(it) }
.doOnNext { publishState(it) }
.startWith(NetworkState.Loading())
}
}
我试图通过以上目标实现的目标:
应用一致的调度程序
通过返回我的密封类的实例来处理任何错误。
通过发布可观察者返回的状态来处理任何onNext。
通过发送加载状态开始。
这在大多数情况下都可以正常工作,但是我注意到的是,虽然我调用
startWith
和加载状态,但实际上并没有由doOnNext()
处理。换句话说,publishState()
永远不会调用我的加载状态。在我设置可观察对象的地方,我不必费心添加一个订户,因为上面的
doOnNext()
是我所需要的:val subscription = repository.getInstagramPhotos(count)
.map { mapIGPhotoResponse(it) }
.compose(applyTransformations())
.subscribe()
但是,如果我要在上面提供一个订户,它将处理加载状态。它还将处理两个
onNext()
调用-一个用于提供的订户,一个用于doOnNext
转换。有没有办法修改此
startWith
调用以发出我在doOnNext
中指定的内容?我正在使用RxJava 1。编辑:只是要澄清更多,如果我跟踪发出了什么,我希望看到两件事。
Loading -> Success
。我实际看到的只是Success
。如果我为可观察对象提供订户,则会看到Loading -> Success -> Success
。 最佳答案
startWith
应该在doOnNext
之前。
Rxjava方法虽然看起来好像使用了构建器模式,但实际上却没有。每次应用运算符时,它们都会返回一个新的可观察值。在您的情况下,您的doOnNext observable在您开始使用observable之前完成,因此不会使用startWith中提供的内容来调用它的使用者。
理想情况下,您应该选择:
observable
.startWith(NetworkState.Loading())
.doOnNext { publishState(it) }
.onErrorReturn { NetworkState.Error(it) }
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
另外,如果没有
onEror
订阅,请谨慎行事。由于您没有任何消耗onError的内容,因此RxJava将使您的应用程序崩溃,因为它没有任何通知错误的信息。如果您想忽略它,请考虑将doOnNext
替换为subscribe中的Success使用者,并使用一个空的Consumer作为错误。同样,
doOnNext
通常用于副作用,例如日志记录和排序,它们比真正的函数运算符更方便。