如何累积多个可观察量并在一段时间后发出最新值(去抖动)

时间:2017-09-12 20:06:34

标签: java android rx-java rx-android rx-java2

我正在尝试实现以下想法

我有一些常规发出事件的对象,但我只对最近的事件感兴趣。这是它在代码中的样子

private void someEvent() {
    List<Object> data = new ArrayList<>();
    // do something
    addEventObservable(generateEventObservable(companyIds));
}

private Observable<SomeValue> generateEventObservable(List<Object> object) {
   // generate observable in this case fetch some data from network
}

private void addEventObservable(Observable<SomeValue> observ) { 
   // Accumulate all incoming observables, but emit the most recent one
   // Get result ad invoke callback
}

考虑someEvent是输入文本的事件,在每个类型的字符上我生成一个observable并传递它addEventObservable。在这个方法中,我需要以某种方式累积所有收到的可观察量,并且只在一段时间后运行最近的一个。

我可以使用计时器来实现这一点,或者通过添加到某个Queue对象来延迟发布。但也许有任何方法可以使用RxJAva elegantelly实现这一点吗?

1 个答案:

答案 0 :(得分:0)

您可以使用RxBinding库('com.jakewharton.rxbinding:rxbinding:1.0.1')将视图转换为流。

首先,将EditText转换为Observable流。这会发出文本更改的事件,就像TextWatcher

一样
    RxTextView.textChanges(companyIdsEditText)

然后,正如标题所示,您可以使用debounce运算符等待用户输入暂停。在这里我将它应用于等待用户输入暂停500ms:

    RxTextView.textChanges(companyIdsEditText)
            .debounce(500, TimeUnit.MILLISECONDS)

您可以进一步应用一些可选过滤,例如,如果公司ID的最小长度为五个字符:

    RxTextView.textChanges(companyIdsEditText)
            .debounce(500, TimeUnit.MILLISECONDS)
            .filter(new Func1<CharSequence,Boolean>() {
                @Override
                public Boolean call(CharSequence charSequence) {
                    return charSequence != null && charSequence.toString().length() >= 5;
                }
            })

现在您已准备好根据您的用户输入进行网络通话。要这样做,我们将flatMap()用户输入,以便为结果类型创建另一个Observable

    RxTextView.textChanges(companyIdsEditText)
            .debounce(500, TimeUnit.MILLISECONDS)
            .filter(new Func1<CharSequence,Boolean>() {
                @Override
                public Boolean call(CharSequence charSequence) {
                    return charSequence != null && charSequence.toString().length() >= 5;
                }
            })
            .flatMap(new Func1<CharSequence,Observable<SomeDataType>>() {
                @Override
                public Observable<SomeDataType> call(CharSequence s) {
                    // make network call and return your result here...
                    // returning null here as a substitute for actual data...
                    return null;
                }
            })

最后,除非我们订阅我们的Observable实例,否则不会发生任何事情:

    RxTextView.textChanges(companyIdsEditText)
            .debounce(500, TimeUnit.MILLISECONDS)
            .filter(new Func1<CharSequence,Boolean>() {
                @Override
                public Boolean call(CharSequence charSequence) {
                    return charSequence != null && charSequence.toString().length() >= 5;
                }
            })
            .flatMap(new Func1<CharSequence,Observable<SomeDataType>>() {
                @Override
                public Observable<SomeDataType> call(CharSequence s) {
                    // make network call and return your result here...
                    // returning null here as a substitute for actual data...
                    return null;
                }
            })
    .subscribe(
            // onNext handler...
            // onError handler...
            // onComplete handler...
    );

我希望有所帮助!