Je recherche un opérateur pour debounce
une série d'événements, disons le clic de l'utilisateur. L'entrée et la sortie doivent être comme ceci:
interval : -> <- -> <-
in : 1--2--3-------4--5--5--6-7-8--------
out : 1-------------4---------------------
L'idée est comme le rebond du soulignement avec immediate
option on
http://underscorejs.org/#debounce . L'opérateur peut être présenté/implémenté dans n'importe quel langage prenant en charge les extensions réactives
Edit: Clarifiez l'intervalle, disons 5 secondes (5 espaces entre deux flèches): -> <-
Edit2: Une version plus compréhensible: j'ai un utilisateur, il clique à plusieurs reprises sur un bouton (1, 2, 3); Je veux attraper le premier click
(1) et ignorer le reste. Après un certain temps, il est fatigué et se repose pendant 7 secondes (ce qui est plus long que l'intervalle de 5 secondes entre deux flèches) et continue de cliquer à nouveau sur le bouton (4, 5, 6, 7, 8) Je veux attraper le premier click
(4) et ignorez le reste.
S'il clique après la quatrième flèche, je veux aussi attraper ce clic.
Edit3: Voici une image qui peut être trouvé sur le article d'origine
Edit: D'après les clarifications, RxJava n'a pas d'opérateur pour ce type de flux mais il peut être composé d'un ensemble non trivial d'autres opérateurs:
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()))
);
}
}
Le comportement souhaité n'est pas celui de l'opérateur debounce
dans Rx.
Cela s'appelle throttle
, throttleTime
ou throttleWithTimeout
(cependant, il appartient à la catégorie d'opérateurs debounce
). Je ne sais pas quelle langue vous utilisez mais dans RxJS, cela ressemble à l'image suivante:
Voir http://reactivex.io/documentation/operators/debounce.html .
Étant donné que debounce()
est intrinsèquement asynchrone, vous devez ramener le résultat au thread actuel de manière explicite.
seriesOfUnfortunateEvents
.debounce( 14, TimeUnit.MILLISECONDS )
.observeOn( Schedulers.immediate() )
.subscribe( v -> yourStuff() );
Selon documentation il y a deux opérateurs anti-rebond dans RxJS. Vous pourriez être intéressé par debounceTime
en particulier.
debounceTime
À partir de la documentation
N'émet une valeur de la source Observable qu'après un laps de temps donné sans autre émission de source.
Exemple:
Rx.Observable
.fromEvent(document.querySelector('button'), 'click')
.debounceTime(200)
.mapTo(() => 'clicked!')
.subscribe(v => console.log(v));
Il en émettra un cliqué ! si le bouton a été cliqué dans un intervalle de temps donné (200 ms dans cet exemple).
debounce
À partir de la documentation
N'émet une valeur de la source observable qu'après un laps de temps particulier déterminé par un autre observable s'est écoulé sans autre émission de la source.