Повторите запрос X раз или пока не будет возвращено Y элементов

#android #rx-java #reactive-programming #rx-java2 #rx-java3

#Android #rx-java #реактивное программирование #rx-java2 #rx-java3

Вопрос:

У меня возникли проблемы с созданием наблюдаемого при следующих условиях:

  1. Извлекайте элементы из API. API может возвращать от 0 до 10 элементов.
  2. Если возвращается менее 10 элементов, запросите больше элементов из API.
  3. Повторите 5 раз или пока не будет собрано 10 или более элементов.

Пока у меня есть это наблюдаемое:

 fetchData().flatMapIterable { dataList }
            .distinct()
            .filter { --some filtering--- }
            .repeat(5)
            .take(10)
            .toList()
 

Это работает нормально, с одной придиркой. Если API возвращает 9 элементов, а затем 10 элементов, наблюдаемый возвращает 10 элементов. Остальные 9 отбрасываются, и я этого не хочу. Есть ли способ заставить его работать таким образом?

Ответ №1:

Соберите его в список, общий для нескольких шагов, и выполните условный повтор:

 Single.defer {
    var list = ArrayList<T>()
    var count = AtomicInteger()

    fetchData()
    .flatMapIterable { dataList }
    .distinct()
    .filter { --some filtering--- }
    .collectInto(list, { list, item -> list.add(item) })
    .repeatUntil { list.size() >= 10 || count.getAndIncrement() > 4 }
    .ignoreElements()
    .andThen(Single.just(list))
}
 

Комментарии:

1. Ах, хорошо. Я уже пробовал что-то в этом роде, но мне не понравилось иметь отдельный список и подсчеты вне потока.