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