Преобразование может быть в одиночку из другого источника, если возможно завершено

Я хотел бы создать класс Repository который возвращает Single<Something> .

Сначала класс должен выглядеть в Cache который возвращает Maybe<Something> и если « Maybe завершается в мою 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, но не кажется, что существует трансформатор для этого сценария.

Есть ли хороший способ справиться с этим?

Вот два довольно простых варианта, которые вы могли бы использовать. Первый я нахожу более явным. Второе имеет преимущество, которое вы вызовете в сети при любой ошибке в кеше.

Они предполагают, что Maybe возвращается из кеша. Например, если в кеше нет значения, верните Maybe.empty ()

1) Если в потоке пуст, switchIfEmpty () будет использовать альтернативный наблюдаемый, который вызывает сеть. Если в потоке не пусто, сеть никогда не будет вызвана.

 override fun getSomething(): Single<Something> { return cache.getSomething() .switchIfEmpty( Maybe.defer { feed.getSomething().toMaybe() } ) .toSingle() } 

2) Возможно, пустая ошибка будет возвращена при запуске 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. Затем вы можете проверить первое уведомление, и если оно имеет значение, используйте это. В противном случае сделайте свой сетевой вызов.