我正在使用Retrofit
进行API调用,该API返回一个Single
,并且我使用onErrorReturn
将任何异常转换为默认对象。我希望消费者看到当前值,但是如果当前值是默认对象,我想尝试重新查询API并另外发送结果。使事情复杂化的是,我可能有多个订阅者。
因此,我知道Retrofit
Single
必须转换为适当的Observable
流,而不仅仅是像普通{那样的onNext
/ onComplete
{1}}可以,但是我不知道如何仅使用Single.toObservable
中的Single
来重新查询API并将值推回给以前的订阅者。
现在,我知道了
Retrofit
但是我知道调用fun request(): Observable<Foo> {
if (behaviorSubject.value == defaultObject) {
API
.request()
.onErrorReturn(defaultObject)
.subscribe(behaviorSubject)
}
return behaviorSubject
}
违反了Rx链接,所以我试图找出解决方法。
答案 0 :(得分:0)
感谢您提出有趣的情况。我认为这是一个可以满足您要求的解决方案。它比您的解决方案更长,但在涉及多个订阅时应该是安全的。
// subscribe to this observable with one or more subscribers
val requestObservable = replayAndRetry(API.request(), defaultObject)
private fun <T> replayAndRetry(request: Single<T>, defaultValue: T): Observable<T> {
val responses = BehaviorSubject.create<T>()
val initialRequest = request
.onErrorReturnItem(defaultValue)
.doOnSuccess(responses::onNext)
.ignoreElement()
.cache() // run the initial request at most once
val retryWhenNecessary = Maybe
.fromCallable { if (responses.value == defaultValue) true else null }
.flatMapCompletable { request
.doOnSuccess(responses::onNext)
.ignoreElement()
.onErrorComplete() // subject already has the default value
}
.toObservable<T>().share() // avoid multiple simultaneous retries
return responses // source for all responses
.mergeWith(initialRequest) // will run once and then complete
.mergeWith(retryWhenNecessary) // will check for default item on every subscription
// will not run simultaneous retries
}