web-dev-qa-db-ja.com

Rxでの即時デバウンス

一連のイベントdebounceのオペレーターを探しています。ユーザーのクリックとしましょう。入力と出力は次のようになります。

interval :      ->     <-            ->     <-
in       : 1--2--3-------4--5--5--6-7-8--------
out      : 1-------------4---------------------

アイデアは、immediateオプションonhttp://underscorejs.org/#debounce によるアンダースコアのデバウンスのようなものです。オペレーターは、R​​eactive Extensionsをサポートする任意の言語で提示/実装できます

編集:間隔を明確にします。たとえば、5秒(2つの矢印の間に5つのスペース)とします:-> <-

Edit2:より理解しやすいバージョン:私はユーザーがいて、彼はボタン(1、2、3)を繰り返しクリックします。最初のclick(1)をキャッチし、残りは無視したい。しばらくして、彼は疲れて7秒間休憩します(これは2つの矢印の間隔である5秒よりも長くなります)。もう一度ボタンをクリックし続けます(4、5、6、7、8)最初のclick(4)そして残りを無視します。

彼が4番目の矢印の後にクリックした場合、そのクリックもキャッチしたいと思います。

Edit3:ここに画像があります imageオリジナル記事 にあります

17
Quang Linh Le

編集:説明に基づいて、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()))
            );
    }
}
14
akarnokd

希望する動作は、Rxでのdebounce演算子の動作とは異なります。

これはthrottlethrottleTimeまたはthrottleWithTimeoutと呼ばれます(ただし、演​​算子のdebounceカテゴリに分類されます)。どの言語を使用しているかはわかりませんが、RxJSでは次の画像のようになります。

enter image description here

http://reactivex.io/documentation/operators/debounce.html を参照してください。

9
martin

debounce()は本質的に非同期であるため、結果を現在のスレッドに明示的に戻す必要があります。

seriesOfUnfortunateEvents
  .debounce( 14, TimeUnit.MILLISECONDS )
  .observeOn( Schedulers.immediate() )
  .subscribe( v -> yourStuff() );
1
Bob Dalgleish

documentation によると、RxJSには2つのデバウンス演算子があります。特にdebounceTimeに興味があるかもしれません。

debounceTime

ドキュメントから

別のソースエミッションが発生せずに特定の期間が経過した後にのみ、ソースObservableから値を発行します。

例:

Rx.Observable
    .fromEvent(document.querySelector('button'), 'click')
    .debounceTime(200)
    .mapTo(() => 'clicked!')
    .subscribe(v => console.log(v));

指定されたタイムスパン(この例では200ミリ秒)でボタンがクリックされた場合、clicked!が発生します。

debounce

ドキュメントから

別のObservableによって決定された特定の期間が別のソースエミッションなしで経過した後にのみ、ソースObservableから値を発行します。

1