我有一个Observable,从网络获取数据。
问题是,observable的执行速度取决于网络条件,可能快也可能慢。
在observable正在执行时,我会显示进度小部件,并在observable完成后隐藏它。当网络很快时,进度会闪烁(出现和消失)。我想将observable的最短执行时间设置为1秒钟。该如何做?
"Delay"运算符不是一个选项,因为它甚至会延迟慢网络的observable。
Observable.zip()
实现这一点。鉴于Observable<Response> network = ...
一个人可以做:
Observable<Integer> readyNotification = Observable.just(42).delay(1, TimeUnit.SECONDS);
Observable delayedNetwork = network.zipWith(readyNotification,
(response, notUsed) -> response);
使用Observable.concatEager()
它允许您强制一个流在另一个流之后完成(concat运算符),但也立即启动网络请求,而无需等待第一个参数可观察对象完成(concatEager):
Observable<Response> responseObservable = ...;
Observable<Response> responseWithMinDelay = Observable.concatEager(
Observable.timer(1, TimeUnit.SECONDS).ignoreElements(),
responseObservable
).cast(Response.class);
我觉得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 */ }
timer
?mergeDelayError
,然后使用例如reduce
将两个项目转换为一个。mergeWithDelay
将确保,如果一个序列中断,另一个序列要么成功完成,要么返回错误(而不是过早取消订阅)。这取决于问题作者想要实现的内容。 - marwinXXII