我正在寻找debounce
一系列活动的运营商,让我们说出用户的点击。输入和输出应该是这样的:
interval : -> <- -> <-
in : 1--2--3-------4--5--5--6-7-8--------
out : 1-------------4---------------------
这个想法就像使用immediate
选项on
http://underscorejs.org/#debounce进行下划线辩护一样。可以使用支持Reactive Extensions的任何语言呈现/实现运算符
编辑:澄清间隔,比方说5秒(两个箭头之间有5个空格):-> <-
Edit2:一个更易理解的版本:我有一个用户,他反复点击一个按钮(1,2,3);我想抓住第一个click
(1)并忽略其余的。过了一会儿,他累了,休息了7秒钟(比两个箭头之间的5秒间隔长)并继续再次点击按钮(4,5,6,7,8)我想抓住第一个{{ 1}}(4)并忽略其余部分。
如果他在第四个箭头后点击,我也想抓住那个点击。
Edit3:这是的图片,可在original article
找到答案 0 :(得分:10)
编辑:根据这些说明,RxJava没有这种类型流的运算符,但它可以由一组非常重要的其他运算符组成:
import java.util.concurrent.TimeUnit;
import rx.Observable;
public class DebounceFirst {
public static void main(String[] args) {
Observable.just(0, 100, 200, 1500, 1600, 1800, 2000, 10000)
.flatMap(v -> Observable.timer(v, TimeUnit.MILLISECONDS).map(w -> v))
.doOnNext(v -> System.out.println("T=" + v))
.compose(debounceFirst(500, TimeUnit.MILLISECONDS))
.toBlocking()
.subscribe(v -> System.out.println("Debounced: " + v));
}
static <T> Observable.Transformer<T, T> debounceFirst(long timeout, TimeUnit unit) {
return f ->
f.publish(g ->
g.take(1)
.concatWith(
g.switchMap(u -> Observable.timer(timeout, unit).map(w -> u))
.take(1)
.ignoreElements()
)
.repeatWhen(h -> h.takeUntil(g.ignoreElements()))
);
}
}
答案 1 :(得分:6)
您想要的行为不是debounce
运算符在Rx中的行为。
这称为throttle
,throttleTime
或throttleWithTimeout
(但是,它属于debounce
类别的运营商)。我不知道你使用的语言,但在RxJS中,它看起来像下图:
请参阅http://reactivex.io/documentation/operators/debounce.html。
答案 2 :(得分:1)
因为debounce()
本质上是异步的,所以需要将结果显式地返回到当前线程。
seriesOfUnfortunateEvents
.debounce( 14, TimeUnit.MILLISECONDS )
.observeOn( Schedulers.immediate() )
.subscribe( v -> yourStuff() );
答案 3 :(得分:1)
根据documentation,RxJS中有两个去抖操作符。您可能特别感兴趣{。{1}}。
debounceTime
来自文档
仅在经过特定时间跨度而没有其他源发射后才从源Observable发出值。
示例:
debounceTime
如果在给定的时间内点击按钮(在本例中为200ms),它将发出一个点击!。
Rx.Observable
.fromEvent(document.querySelector('button'), 'click')
.debounceTime(200)
.mapTo(() => 'clicked!')
.subscribe(v => console.log(v));
来自文档
仅在特定时间后从源Observable发出值 由另一个Observable决定的跨度没有另一个 源排放。