Задать вопрос
mitaichik
@mitaichik

Rx: как повторять подписку до определенного результата?

Всем привет!

Не могу точно сформулировать вопрос, опишу что надо:

Есть Single<SomeObject> - запрос через Retrofit.
У SomeObject есть поле status
И мне нужно повторять этот запрос до тех пор, пока это поле не примет определенное значение.
И только после этого subscribe должен получить результат.

Что то типа repeatWhen, но в repeatWhen я не могу получить возвращенный SomeObject чтоб проверить статус (я так понял из документации).

Есть ли способ сделать такое элегантно, чисто на Rx?

Заранее спасибо!
  • Вопрос задан
  • 204 просмотра
Подписаться 2 Простой Комментировать
Пригласить эксперта
Ответы на вопрос 3
@tuwkan
В map проверять значение и если не оно кидать ошибку. Далее retryWhen
Ответ написан
Комментировать
Можно использовать рекурсивно switchMap.
Если результат удовлетворителен, то возвращать его обернув в just. Иначе вернуть новый Single, дёрнув ту же функцию.

Предусмотрите задержку.
Ответ написан
Комментировать
Я не конечно не мастер Rx, но натолкнулся на эту статью на хабре Постигаем retryWhen и repeatWhen

Кусок кода из статьи, применительный к вашей проблему
public void load() {
    Observable.combineLatest(
            repository.getSomething()
                    .retryWhen(retryHandler ->
                                       retryHandler.flatMap(
                                               err -> retrySubject.asObservable())),
            localStorage.fetchSomethingReallyHuge()
                    .retryWhen(retryHandler ->
                                       retryHandler.flatMap(
                                               nothing -> retrySubject.asObservable())),
            (something, hugeObject) -> new Stuff(something, hugeObject))
            .subscribe(stuff -> {}, err -> {});
}

Прелесть такого подхода в том, что лямбда, переданная в оператор retryWhen() исполняется только после ошибки внутри источника, соответственно, если «ошибется» только один из источников, то и переподписка произойдет только на него, а оставшаяся цепочка ниже будет ожидать переисполнения.

А если ошибка произойдет внутри обоих источников, то один и тот же retryHandler сработает в двух местах.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы