Created
April 27, 2018 15:56
-
-
Save lovasoa/b35593683cb7d737b4789992656afbae to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.qwant.debouncer; | |
import java.util.ArrayList; | |
import java.util.List; | |
import java.util.concurrent.CompletableFuture; | |
import java.util.concurrent.Executors; | |
import java.util.concurrent.ScheduledExecutorService; | |
import java.util.concurrent.TimeUnit; | |
import java.util.function.Function; | |
public class Debouncer<T, U> implements Function<T, CompletableFuture<U>> { | |
private final List<T> waitingArgs = new ArrayList<>(); | |
private final long delay; | |
private CompletableFuture<List<U>> nextResults = new CompletableFuture<>(); | |
private Function<List<T>, CompletableFuture<List<U>>> multiFun; | |
private ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); | |
public Debouncer(Function<List<T>, CompletableFuture<List<U>>> multiFun, long delay) { | |
this.multiFun = multiFun; | |
this.delay = delay; | |
} | |
public static <T, U> Debouncer<T, U> synchronous(Function<List<T>, List<U>> multiFun, long delay) { | |
return new Debouncer<T,U>(multiFun.andThen(CompletableFuture::completedFuture), delay); | |
} | |
@Override | |
public synchronized CompletableFuture<U> apply(T t) { | |
int position = waitingArgs.size(); | |
waitingArgs.add(t); | |
scheduler.schedule(this::fire, this.delay, TimeUnit.MILLISECONDS); | |
return nextResults.thenApply(list -> list.get(position)); | |
} | |
private synchronized void fire() { | |
if (waitingArgs.isEmpty()) return; | |
CompletableFuture<List<U>> results = this.multiFun.apply(waitingArgs); | |
waitingArgs.clear(); | |
CompletableFuture<List<U>> previousResults = nextResults; | |
results.whenCompleteAsync((res, err) -> { | |
if (err != null) previousResults.completeExceptionally(err); | |
else previousResults.complete(res); | |
}); | |
nextResults = new CompletableFuture<>(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment