Debounce заставляет PublishSubject выдавать только один элемент

protected PublishSubject<Integer> onScrollS = PublishSubject.create();

public void onActivityCreated(...) {

        ...

        recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrolled(@NotNull RecyclerView recyclerView, int dx, int dy) {
                if (dy == 0) return;
                Log.i("Rx", "onNext(" + dy + ")");
                onScrollS.onNext(dy);
            }
        });
        disposable = onScrollS
                .debounce(200, TimeUnit.MILLISECONDS) // <-- this breaks everything
                .subscribe(this);
    }

    // the Fragment implements Consumer interface
    @Override
    public void accept(Integer integer) throws Exception {
        Log.i("Rx", "Accept: " + integer);
        recyclerViewOnScrolled();
    }

Когда я добавляю .debounce вызов к моей теме onScrollS, метод accept вызывается только один раз.

Я могу прокручивать и прокручивать, затем останавливаюсь на десять секунд, и ничего не происходит.

Кто-нибудь знает почему?

Я пробовал что-то вроде этого:

.debounce((Function<Integer, Observable<Integer>>) value - > {
    return Observable.just(value).delay(1, TimeUnit.SECONDS);
})

И работает, если убрать delay часть.


person Jerzy Kiler    schedule 28.04.2020    source источник


Ответы (1)


здесь может быть несколько проблем:

  • Подпишитесь на события прокрутки перед добавлением OnScrollListener
  • Добавьте обработчик потока в поток Rx, чтобы быть уверенным, что вы подписываете поток на поток ввода-вывода и наблюдаете за основным потоком
  • Также вы можете сразу добавить реализацию onNext в метод подписки
    onScrollS
                .debounce(200, TimeUnit.MILLISECONDS)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer dy) throws Exception {
                        // TODO handle scroll event
                    }
                });
person lbasek    schedule 28.04.2020
comment
Спасибо, subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()) исправил это, но почему мне нужно переходить в другой поток только для того, чтобы отклонить эти элементы? Это где-то указано в документации? - person Jerzy Kiler; 29.04.2020
comment
Да, debounce работает по умолчанию в планировщике вычислений, поэтому вы должны знать об этом и обрабатывать подписку subscribeOn / ObserverOn самостоятельно. Это также хорошая и рекомендуемая практика. - person lbasek; 29.04.2020