Преобразовать Maybe в Single из другого источника, если Maybe завершается
Я хотел бы построить Repository
класс, который возвращает Single<Something>
.
класс должен сначала посмотреть в Cache
возвращает Maybe<Something>
и если Maybe
завершает go off to my Service
возвращает Single<Something>
interface Cache {
fun getSomething(): Maybe<Something>
}
interface Service {
fun getSomething(): Single<Something>
}
class Repository (
private val cache: Cache,
private val service: Service
) {
fun getSomething(): Single<Something> {
return cache.getSomething()
.????(feed.getSomething()) //onCompleteTransformToSingle() or similar
}
}
Я искал через JavaDoc, но не похоже, что трансформатор для этого сценария существует.
есть хороший способ справиться с этим?
2 ответов
вот два довольно простых варианта, которые вы можете использовать. Первое я нахожу более явным. Второй имеет то преимущество, что вы будете вызывать сеть при любой ошибке в кэше.
Они предполагают, что возможно возвращается из кэша. Например, если в кэше не найдено никакого значения, возможно возврат.пустой()
1) Если в потоке есть пустое, switchIfEmpty () будет использовать альтернативный наблюдаемый, который вызывает сеть. Если в потоке нет пустого, сеть никогда не будет называемый.
override fun getSomething(): Single<Something> {
return cache.getSomething()
.switchIfEmpty(
Maybe.defer {
feed.getSomething().toMaybe()
}
)
.toSingle()
}
2) пустое maybe вернет ошибку при приведении toSingle (), вызывая сетевой вызов.
override fun getSomething(): Single<Something> {
return cache.getSomething()
.toSingle()
.onErrorResumeNext {
feed.getSomething()
}
}
когда вам нужно выполнить операции RxJava с использованием метаданных (отсутствие кэшированного результата), вам может потребоваться преобразовать цепочку наблюдателей в поток метаданных, используя materialize()
.
(извиняюсь за отсутствие беглости в Котлине)
fun getSomething(): Single<Something> {
return cache.getSomething()
.toObservable()
.materialize()
.take(1)
.flatMap( it.hasValue() ? Single.just( it.getValue() )
: Single.fromCallable( apiCall() )
);
}
на materialize()
оператор превращает поток наблюдателя в поток Notification
s. Затем вы можете проверить первое уведомление, и если оно имеет значение, используйте его. В противном случае позвоните по сети.