从队列项中停止java rx interval observable

时间:2017-04-14 21:41:59

标签: rx-java

我有一个Observable.interval,每隔10秒发出一个项目。在我的订户内部,我有一个同步操作,有时持续超过10秒。结果是我的observable每10秒发出一次,所以当同步操作结束时,订户会连续多次被调用。

这就是我所拥有的:

Observable.interval(0, 10, TimeUnit.SECONDS)
    .subscribeOn(Schedulers.io())
    .subscribe(new Action1<Long>() {
        @Override
        public void call(Long aLong) {
            aSynchronousOperation(); // Last more than 10 seconds
         }
     });

我想做的可能是&#34; flush&#34;完成同步操作后的可观察性。

我该怎么做?

2 个答案:

答案 0 :(得分:1)

问题是observeOn尊重背压并会缓冲间隔时的排放,并在用户完成其工作时排放。
实际上你理论上可以得到MissingBackpressureException,因为默认缓冲区可能会溢出(理论上是因为你的10秒间隔很长)。
你想要的是在你正在处理的时候丢弃物品,这可以通过简单的旗帜来实现,filter,这将防止你的工作进行中的任何排放。

请注意,如果您提及工作时间超过10秒,那么在工作完成后您将无法收到interval的通知,再过10秒。你可以通过实施不同的策略来轻松改变它,让过滤器在工作进行中之后传递单个值,然后阻止额外的排放。

 AtomicBoolean workInProgress = new AtomicBoolean(false);
    Observable.interval(10, TimeUnit.SECONDS)
            .filter(aLong -> !workInProgress.get())
            .observeOn(Schedulers.io())
            .subscribe(aLong -> {
                workInProgress.set(true);
                aSynchronousOperation();
                workInProgress.set(false);
            });

答案 1 :(得分:1)

此案例的规范运算符为onBackPressureDrop

Observable
.interval(0, 10, TimeUnit.SECONDS)
.subscribeOn(Schedulers.io())
.onBackPressureDrop()
.subscribe(new Action1<Long>() {
    @Override
    public void call(Long aLong) {
        aSynchronousOperation(); // Last more than 10 seconds
     }
 });