RxJava Наблюдаемое минимальное время выполнения

У меня есть Observable (который получает данные из сети). Проблема в том, что observable может быть быстрым или медленным в зависимости от состояния сети.

Я показываю виджет прогресса, когда выполняется наблюдаемое, и скрываю его, когда наблюдаемое завершается. Когда сеть быстрая - прогресс мерцает (появляется и пропадает). Я хочу установить минимальное время выполнения наблюдаемого на 1 секунду. Как я могу это сделать?

Оператор «Задержка» не подходит, потому что он будет задерживать даже для медленной сети.


person wilddev    schedule 27.06.2016    source источник


Ответы (3)


Вы можете использовать Observable.zip() для этого. Дано

Observable<Response> network = ...

можно сделать

Observable<Integer> readyNotification = Observable.just(42).delay(1, TimeUnit.SECONDS);
Observable delayedNetwork = network.zipWith(readyNotification, 
                                                (response, notUsed) -> response);
person m.ostroverkhov    schedule 27.06.2016
comment
1) Почему бы не использовать только timer? 2) Обратите внимание, что сеть может выйти из строя до истечения времени ожидания. Если вы хотите, чтобы время ожидания всегда использовалось, попробуйте mergeDelayError, а затем используйте, например, reduce, чтобы преобразовать два элемента в один. - person marwinXXII; 29.06.2016
comment
2) можно решить с помощью materialize() сразу после network и dematerialize() после zipWith(). Не уверен в актуальности mergeDelayError() для предлагаемого решения - вы можете прокомментировать исходный вопрос или добавить его в качестве другого ответа - person m.ostroverkhov; 29.06.2016
comment
mergeWithDelay гарантирует, что если одна последовательность прервется, другая последовательность либо успешно завершится, либо вернет ошибку (и не отпишется преждевременно). Зависит от того, какой вопрос автор хочет реализовать. - person marwinXXII; 30.06.2016

Используйте 1_

Это позволяет принудительно завершать один поток за другим (оператор concat), а также немедленно запускать сетевой запрос, не дожидаясь завершения первого наблюдаемого аргумента (concatEager):

Observable<Response> responseObservable = ...;

Observable<Response> responseWithMinDelay = Observable.concatEager(
                    Observable.timer(1, TimeUnit.SECONDS).ignoreElements(),
                    responseObservable
).cast(Response.class);
person Rich Ehmer    schedule 30.06.2017

Казалось, что Observable.zip будет разумным подходом, и он, казалось, работал хорошо, пока не возникла ошибка; то он не ждал ожидаемого времени.

Это, казалось, хорошо сработало для меня:

Observable.mergeDelayError(
        useCase.execute(), // can return Unit or throw error
        Observable.timer(1, TimeUnit.SECONDS)
)
.reduce { _, _ -> Unit }
.doOnError { /* will wait at least 1 second */ }
.subscribe { /* will wait at least 1 second */ }
person Ben Pearson    schedule 01.02.2019