RxJava反跳操作符仅显示Android上的最后一次发射

时间:2018-08-25 15:38:16

标签: android reactive debounce

我正在尝试在Android上使用RxJava在1秒后发出数字。

但是,只有最后一项(7)被发出。

我在做什么错了?

private Observable<Integer> getIntegerObservable(){
    return Observable.just(1,2,3,4,5,6,7);
}

getIntegerObservable()
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .debounce(1, TimeUnit.SECONDS)
                    .subscribe(new Observer<Integer>() {
                        @Override
                        public void onSubscribe(Disposable d) {

                        }

                        @Override
                        public void onNext(Integer integer) {
                            textView.setText(textView.getText().toString() + String.valueOf(integer)+"\n");
                        }

                        @Override
                        public void onError(Throwable e) {
                            System.out.println(e.getMessage());
                        }

                        @Override
                        public void onComplete() {

                        }
                    });

2 个答案:

答案 0 :(得分:1)

“反跳”运算符将源Observable发出的项目过滤掉,然后迅速跟上另一个发出的项目。

在您的情况下,数字1到7在一秒钟内都发出了。 指定去抖动的窗口为一秒钟。一秒结束时发出的最新项目是7,因此所有其他项目都被过滤掉,您将收到7作为输出。

下图显示了在一个时间范围内连续发射6件物品的情况。仅第六项将通过,其他将被过滤。 Debounce for 6 items

下图显示了另一种情况,即在一个时间段之后发出第六项,因此同时发出第五项和第六项,同时过滤其他项。 enter image description here

希望这会有所帮助,请尝试在documentation网站上使用大理石图。

答案 1 :(得分:1)

documentation所说

  

去抖动仅在经过特定时间跨度后才从Observable中发出一项,而不会发出另一项。过滤掉   源Observable发出的项目很快被跟随   另一个发射的物品。

由于您的情况,所有项目均在时间窗口内发出。仅显示最新的项目,所有其他项目都被过滤掉。

我想您正在寻找的是Delay

  

Delay (延迟)操作符通过暂停   发出每个信号之前的特定时间增量(由您指定)   源Observable的项目。这具有转移   Observable在时间上向前发射的整个项目序列   指定的增量。

因此,它应该看起来像这样:

getIntegerObservable()
          .delay(1, TimeUnit.SECONDS)
          .subscribeOn(Schedulers.io())
          .observeOn(AndroidSchedulers.mainThread())
          .subscribe(...);

您还应该考虑在delay(..)之前调用subscribeOn(..),以避免阻塞主线程

查看此article,它说明了subscribeOnobserveOn之间的区别

更新

您可以将CountDownTimer包裹在Obserable中。例如:

Observable.create(emitter -> new CountDownTimer(7000, 1000) {

          public void onTick(long millisUntilFinished) {
                 emitter.onNext(millisUntilFinished / 1000);
           }

           public void onFinish() {
                emitter.onComplete();
           }
         }.start())
.doOnNext() //you can log your timer here
.subscribe(); //or here

奖励(很有趣:D)

RxJava使用Java8看起来更酷

Observable.create(this::startCountDownTimer)
       .doOnNext() //use long value
       .map(String::valueOf) //map to string
       .doOnNext() //use string value
       .doOnComplete() //gets called when the timer is up
       .subscribe(this::handleTick, this::handleError);

倒数方法

private void startCountDownTimer(ObservableEmitter<Long> emitter) {
    new CountDownTimer(7000, 1000) {
        public void onTick(long millisUntilFinished) {
            emitter.onNext(millisUntilFinished / 1000);
        }

        public void onFinish() {
            emitter.onComplete();
        }
    }.start();
}

提手打勾方法

private void handleTick(String timer) {
    //Update UI
}

处理错误的方法

private void handleError(Throwable t) {
    //Log and inform user
}