Rx java Rx中的即时去盎司
我正在寻找一个操作符来消除一系列事件,比如说用户的点击。输入和输出应如下所示:Rx java Rx中的即时去盎司,rx-java,rxjs,system.reactive,debounce,Rx Java,Rxjs,System.reactive,Debounce,我正在寻找一个操作符来消除一系列事件,比如说用户的点击。输入和输出应如下所示: interval : -> <- -> <- in : 1--2--3-------4--5--5--6-7-8-------- out : 1-------------4--------------------- interval:->因为debounce()本质上是异步的,所以需要显式地将结果返回到当前线程 serie
interval : -> <- -> <-
in : 1--2--3-------4--5--5--6-7-8--------
out : 1-------------4---------------------
interval:->因为debounce()
本质上是异步的,所以需要显式地将结果返回到当前线程
seriesOfUnfortunateEvents
.debounce( 14, TimeUnit.MILLISECONDS )
.observeOn( Schedulers.immediate() )
.subscribe( v -> yourStuff() );
据介绍,RxJS中有两个去盎司操作符。您可能特别对debounceTime
感兴趣
debounceTime
来自文档
仅在经过特定时间跨度且没有其他源发射后,才从源发射可观测的值
例如:
Rx.Observable
.fromEvent(document.querySelector('button'), 'click')
.debounceTime(200)
.mapTo(() => 'clicked!')
.subscribe(v => console.log(v));
它会发出一声咔嗒声!如果在给定的时间跨度内(本例中为200ms)单击按钮
debounce
来自文档
仅在特定时间后从源发出可观察的值
由另一个可观察物确定的跨度已经过去,没有另一个可观察物
源排放
您想要的行为不是操作员在Rx中所做的
这被称为throttle
、throttleTime
或throttleWithTimeout
(但是,它属于debounce
操作符类别)。我不知道您使用什么语言,但在RxJS中,它看起来像下图:
请参阅。编辑:根据澄清,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()))
);
}
}
import java.util.concurrent.TimeUnit;
进口接收。可观察;
公共类DebounceFirst{
公共静态void main(字符串[]args){
可观察的。刚好(0,100,200,1500,1600,1800,2000,10000)
.flatMap(v->Observable.timer(v,TimeUnit.millides).map(w->v))
.doOnNext(v->System.out.println(“T=“+v))
.compose(去BounceFirst(500,时间单位毫秒))
.toBlocking()
.subscribe(v->System.out.println(“取消公告:+v”);
}
静态可观察。变压器去BounceFirst(长超时,时间单位){
返回f->
f、 发布(g->
g、 采取(1)
康卡特维思先生(
g、 开关映射(u->Observable.timer(超时,单位).map(w->u))
.采取(1)
.ignoreElements()
)
.repeatWhen(h->h.takeUntil(g.ignoreElements()))
);
}
}
这非常接近,但是让我们假设我想要的间隔是yb
也比bx
长,xc
,xc
我希望输出只包含a
和b
@QuangLinhLe您可以设置任何您想要的间隔。或者我不明白你想要什么…我刚刚编辑了这个问题,时间间隔是从最后两次点击开始的,不是从开始开始的。我仍然认为你准确地描述了油门的功能。请纠正我我的假设是错的。使用油门
并延迟5秒,如果用户重复单击按钮,我将在500秒内收到大约100次单击?我想要的只是第一个。谢谢@Michal,我想要的是当我点击按钮时,有一个点击
事件,然后每隔点击
一次,直到最后两次点击
的间隔超过200秒谢谢@akarnokd。这是正确的实现。我真的很喜欢你的测试代码,并偷了它作为我的答案之一。是的,compose
的想法非常好@有没有可能向我们解释一下你是如何设计出这个工具的?@akarnokd我们可以把它添加为操作员。它感觉像是一个常见的用例,没有找到答案就很难正确实现;您必须非常深入地了解RxJava操作符,并了解底层数据流,才能将这些不同的操作符组合在一起@FriendlyMikhail这是一个不常见的操作符,因为去抖动超时必须一次又一次地延长。也许你可以让rxjava额外人员把它拿到1.x版。2.x在RxJava2Extensions中有此功能。是相关的。