RxJava可观察对象的最小执行时间

4

我有一个Observable,从网络获取数据。

问题是,observable的执行速度取决于网络条件,可能快也可能慢。

在observable正在执行时,我会显示进度小部件,并在observable完成后隐藏它。当网络很快时,进度会闪烁(出现和消失)。我想将observable的最短执行时间设置为1秒钟。该如何做?

"Delay"运算符不是一个选项,因为它甚至会延迟慢网络的observable。

3个回答

7
您可以使用Observable.zip()实现这一点。鉴于
Observable<Response> network = ...

一个人可以做:

Observable<Integer> readyNotification = Observable.just(42).delay(1, TimeUnit.SECONDS);
Observable delayedNetwork = network.zipWith(readyNotification, 
                                                (response, notUsed) -> response);

1
  1. 为什么不只使用 timer
  2. 注意,网络可能在超时之前失败。如果您想确保始终使用超时,请尝试使用 mergeDelayError,然后使用例如 reduce 将两个项目转换为一个。
- marwinXXII
  1. 可以通过在 network 后立即使用 materialize(),并在 zipWith() 后使用 dematerialize() 来解决。不确定 mergeDelayError() 对所提出的解决方案的相关性 - 您可以评论原始问题或将其作为另一个答案添加。
- m.ostroverkhov
mergeWithDelay 将确保,如果一个序列中断,另一个序列要么成功完成,要么返回错误(而不是过早取消订阅)。这取决于问题作者想要实现的内容。 - marwinXXII

1

使用Observable.concatEager()

它允许您强制一个流在另一个流之后完成(concat运算符),但也立即启动网络请求,而无需等待第一个参数可观察对象完成(concatEager):

Observable<Response> responseObservable = ...;

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

1

我觉得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 */ }

我也遇到了同样的错误问题! - new

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接