Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

rxJava debounce() operator not working with Observable.range()

AFAIK, the debounce() operator of rxJava is used for delaying emission of events. When I apply it with the search box it work normally:

RxTextView.textChangeEvents(editText)
                .debounce(1000, TimeUnit.MILLISECONDS) //Only emit after 1 sec
                .subscribe(new Observer<TextViewTextChangeEvent>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(TextViewTextChangeEvent event) {
                        //Get more information about text change event
                        Log.e(TAG, "Before: " + event.before() + ", start: " + event.start() + ", count: " + event.count());
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {
                        Log.e(TAG, "textChangeEvents: onComplete");
                    }
                });

But when I apply it with Observable.range() like this:

Observable.range(1, 10000)
                .debounce(1000, TimeUnit.MILLISECONDS)
                .subscribe(new Observer<Long>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {

                    }

                    @Override
                    public void onNext(@NonNull Long integer) {

                    }

                    @Override
                    public void onError(@NonNull Throwable e) {

                    }

                    @Override
                    public void onComplete() {

                    }
                });

the emission keep coming to onNext() very fast (about 1000 emissions/s) and continuously although I have applied debounce(1000, TimeUnit.MILISECONDS) operator.

Want I am expecting is: when I'm using debounce() only 1 number will be emitted after a delay of 1000 miliseconds (it can skip numbers when delaying between 2 emissions). Means emission will go downstream one by one like the search box example above.

I'm new to rx please help me to achieve this and explain why? I don't really know why I MUST use another operator but debounce() because the idea is the same!

like image 405
nhoxbypass Avatar asked Dec 09 '17 15:12

nhoxbypass


Video Answer


2 Answers

debounce prevents the downstream from getting overwhelmed by defining a grace period which must elapse between events in order to get the last event, in other words, it will emit the latest element after some quiet time. Range will go through its items as fast it can thus there won't be enough time between items and only the very last will be emitted.

debounce is simply not the operator your use case requires. The extensions project for 2.x has the spanout operator for your use case.

like image 134
akarnokd Avatar answered Sep 26 '22 10:09

akarnokd


What you need is per item '.delay()' operator. See description here - http://reactivex.io/RxJava/javadoc/rx/Observable.html#delay-rx.functions.Func1-

Observable
    .range(1, 10000)
    .delay(new Func1<Integer, Observable<Long>>() {
        @Override
            public Observable<Long> call(Integer integer) {
                return Observable.timer(1, TimeUnit.SECONDS );
            }
    });

For the good order, '.debounce()' is absolutely out of question for this use case.

like image 26
Maxim Volgin Avatar answered Sep 25 '22 10:09

Maxim Volgin