Оператор RxJava, такой как replay (1, 1, MINUTE), но который повторно подписывается через 1 минуту - PullRequest
2 голосов
/ 26 сентября 2019

Мне нужен, можно подумать, относительно простой механизм истечения срока действия кэша (скажем, 1 минута).

  1. Когда подписчик первый, я хочу сделать вызов API.
  2. Когда вторая подписывается в течение минуты, я не хочу делать вызов API, но проталкиваю вниз по потоку ранее загруженное значение.
  3. Когда другой подписывается через минуту после первого, я хочу, чтобы был выполнен вызов APIснова.

Теперь я хотел сделать это в одной цепочке rxjava..replay(1, 1, MINUTE) выглядел прекрасно, пока я не узнал, что по прошествии одной минуты наблюдаемый источник не переписывается.Я никогда больше ничего не получу от этого наблюдаемого.Мне, вероятно, нужно что-то, что сливается replay() с repeatWhen{}, но не может его найти.Я попробовал действительно экзотическую комбинацию, и ни одна из них не сработала для моих тестовых случаев.

Ответы [ 2 ]

3 голосов
/ 27 сентября 2019

Возможно, это не лучшее решение, но я бы попытался сделать это следующим образом:

    public final class SimpleCacheSingle<T : Any> constructor(
     val apiRequest: (value: String, callback: (T) -> Unit) -> Unit
 ) {
     private var lastTimeSeconds = 0L
     private lateinit var cachedValue: T

     fun getSingle(): Single<T> = Single.create { emitter ->
         if (System.currentTimeMillis() / 1000 - lastTimeSeconds > 60) {
             apiRequest("example argument") {
                 cachedValue = it
                 lastTimeSeconds = System.currentTimeMillis() / 1000
                 emitter.onSuccess(cachedValue)
             }
         } else {
             emitter.onSuccess(cachedValue)
         }
     }
 }

Просто создайте его экземпляр и используйте getSingle () для создания отдельного для каждого подписчика.

Конечно, «apiRequest» в прикрепленном фрагменте кода необходимо изменить в соответствии с вашими потребностями.

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

0 голосов
/ 26 сентября 2019

Вы можете использовать следующие операторы

  1. .retryWhen () для повторной подписки.
  2. . delay () оператор для задержки подписчика: ЗадержкаОператор изменяет свой источник Observable, делая паузу для определенного приращения времени (которое вы укажете) перед выпуском каждого из элементов Observable источника.Это приводит к сдвигу всей последовательности элементов, излучаемых наблюдаемой вперед, во времени на указанное значение.
...