立即在Rx中去抖动

Qua*_* Le 15 system.reactive rxjs rx-java debounce

我正在寻找debounce一系列事件的运营商,让我们说用户的点击.输入和输出应该是这样的:

interval :      ->     <-            ->     <-
in       : 1--2--3-------4--5--5--6-7-8--------
out      : 1-------------4---------------------
Run Code Online (Sandbox Code Playgroud)

这个想法就像下划线的immediate选择on http://underscorejs.org/#debounce一样.可以使用支持Reactive Extensions的任何语言呈现/实现运算符

编辑:澄清间隔,比如说5秒(两个箭头之间有5个空格): -> <-

Edit2:一个更容易理解的版本:我有一个用户,他反复点击一个按钮(1,2,3); 我想抓住第一个click(1)并忽略其余部分.过了一会儿,他累了,休息了7秒钟(这比两个箭头之间的5秒间隔长)并继续再次点击按钮(4,5,6,7,8)我想赶上第一个click(4并忽略其余的.

如果他在第四个箭头后点击,我也想抓住那个点击.

Edit3:这是一张图片 图片可以在原始文章中找到

aka*_*okd 13

编辑:根据说明,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()))
            );
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我不这么认为; 您必须在非常深入的层面上了解RxJava运算符,并且可以看到基础数据流能够将这些不同的运算符组合在一起.@FriendlyMikhail这是一个不常见的运算符,因为debouncing超时必须反复扩展.也许你可以要求rxjava-extras将其用于1.x. 2.x在RxJava2Extensions中有这个. (2认同)

mar*_*tin 8

您想要的行为不是debounce运营商在Rx中的行为.

这被称为throttle,throttleTimethrottleWithTimeout(但它属于debounce运营商的类别).我不知道你使用的语言,但在RxJS中,它看起来像下图:

在此输入图像描述

请参阅http://reactivex.io/documentation/operators/debounce.html.