Debounce 使 PublishSubject 只发出一项

Posted

技术标签:

【中文标题】Debounce 使 PublishSubject 只发出一项【英文标题】:Debounce makes PublishSubject emit only one item 【发布时间】:2020-04-28 16:29:33 【问题描述】:
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 部分,它会起作用。

【问题讨论】:

【参考方案1】:

这里可能有一些问题:

在添加 OnScrollListener 之前订阅滚动事件 将线程处理程序添加到 Rx 流,以确保您在 IO 线程上订阅流并在主线程上观察 您也可以立即在 subscribe 方法中添加 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
                    
                );

【讨论】:

谢谢,subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()) 修复了它,但为什么我需要移动到另一个线程来消除这些项目的抖动?它是否在文档中的某处指定? 是的,debounce 默认在计算调度程序上运行,因此您必须意识到这一点并自行处理 subscribeOn/observerOn。这也是一种很好的推荐做法。

以上是关于Debounce 使 PublishSubject 只发出一项的主要内容,如果未能解决你的问题,请参考以下文章

RxSwift PublishSubject 单元测试

正在处理 RxSwift PublishSubject

防止处理 PublishSubject (RxSwift)

RxSwift - PublishSubject - 忽略错误并继续订阅(不要处置)

PublishSubject 与 Kotlin 协程(流/通道)

RxJava - 即使调用 onNext() 如何阻止 PublishSubject 发布