RxJava 过滤器行为
RxJava filter behaviour
我编写的代码是 EditText
中的去抖动文本并过滤掉少于 4 个字符的文本:
charSequenceInitialValueObservable.skipInitialValue()
.filter(new Predicate<CharSequence>() {
@Override public boolean test(@NonNull CharSequence charSequence) throws Exception {
Log.d("TAG", "l: " + charSequence.length());
return charSequence.length() > 3;
}
})
.doOnNext(new Consumer<CharSequence>() {
@Override public void accept(@NonNull CharSequence charSequence) throws Exception {
Log.d("TAG", "1. doOnNext: \"" + charSequence + "\"");
}
})
.debounce(300, TimeUnit.MILLISECONDS)
.doOnNext(new Consumer<CharSequence>() {
@Override public void accept(@NonNull CharSequence charSequence) throws Exception {
Log.d("TAG", "2. doOnNext: \"" + charSequence + "\"");
}
})
.subscribeWith(new DisposableObserver<CharSequence>() {
@Override
public void onNext(@io.reactivex.annotations.NonNull CharSequence charSequence) {
Log.d("TAG", "onNext: \"" + charSequence + "\"");
}
@Override public void onError(@io.reactivex.annotations.NonNull Throwable e) {
Log.d("TAG", "onError: " + e.toString());
}
@Override public void onComplete() {
Log.d("TAG", "onComplete");
}
});
当用户输入文本时 - 过滤工作正常,但当用户使用退格键时,最后一个空字符序列被传送到 Subscriber
:
1. doOnNext: "test hhu"
l: 7
1. doOnNext: "test hh"
l: 6
1. doOnNext: "test h"
l: 5
1. doOnNext: "test "
l: 4
1. doOnNext: "test"
l: 3
l: 2
l: 1
l: 0
2. doOnNext: ""
onNext: ""
这是预期的行为吗?去抖动后我应该第二次使用过滤器运算符吗?如何正确过滤掉它?
Debounce 在给定的超时时间内没有传递任何值后通过最后一个值,因此理论上它应该通过 "test"
。
然而,唯一通过的值是 ""
,这可能表明该值不是不可变的,并且在通过去抖运算符之前会被覆盖。
要解决此问题,请确保 charSequenceInitialValueObservable
仅接收不可变值或在 debounce
之前制作防御性副本。 (类似于 .map(cs -> new String(cs))
)
我编写的代码是 EditText
中的去抖动文本并过滤掉少于 4 个字符的文本:
charSequenceInitialValueObservable.skipInitialValue()
.filter(new Predicate<CharSequence>() {
@Override public boolean test(@NonNull CharSequence charSequence) throws Exception {
Log.d("TAG", "l: " + charSequence.length());
return charSequence.length() > 3;
}
})
.doOnNext(new Consumer<CharSequence>() {
@Override public void accept(@NonNull CharSequence charSequence) throws Exception {
Log.d("TAG", "1. doOnNext: \"" + charSequence + "\"");
}
})
.debounce(300, TimeUnit.MILLISECONDS)
.doOnNext(new Consumer<CharSequence>() {
@Override public void accept(@NonNull CharSequence charSequence) throws Exception {
Log.d("TAG", "2. doOnNext: \"" + charSequence + "\"");
}
})
.subscribeWith(new DisposableObserver<CharSequence>() {
@Override
public void onNext(@io.reactivex.annotations.NonNull CharSequence charSequence) {
Log.d("TAG", "onNext: \"" + charSequence + "\"");
}
@Override public void onError(@io.reactivex.annotations.NonNull Throwable e) {
Log.d("TAG", "onError: " + e.toString());
}
@Override public void onComplete() {
Log.d("TAG", "onComplete");
}
});
当用户输入文本时 - 过滤工作正常,但当用户使用退格键时,最后一个空字符序列被传送到 Subscriber
:
1. doOnNext: "test hhu"
l: 7
1. doOnNext: "test hh"
l: 6
1. doOnNext: "test h"
l: 5
1. doOnNext: "test "
l: 4
1. doOnNext: "test"
l: 3
l: 2
l: 1
l: 0
2. doOnNext: ""
onNext: ""
这是预期的行为吗?去抖动后我应该第二次使用过滤器运算符吗?如何正确过滤掉它?
Debounce 在给定的超时时间内没有传递任何值后通过最后一个值,因此理论上它应该通过 "test"
。
然而,唯一通过的值是 ""
,这可能表明该值不是不可变的,并且在通过去抖运算符之前会被覆盖。
要解决此问题,请确保 charSequenceInitialValueObservable
仅接收不可变值或在 debounce
之前制作防御性副本。 (类似于 .map(cs -> new String(cs))
)