Rico Kahler :
I have this weird type CompletableFuture<CompletableFuture<byte[]>>
but i want CompletableFuture<byte[]>
. Is this possible?
public Future<byte[]> convert(byte[] htmlBytes) {
PhantomPdfMessage htmlMessage = new PhantomPdfMessage();
htmlMessage.setId(UUID.randomUUID());
htmlMessage.setTimestamp(new Date());
htmlMessage.setEncodedContent(Base64.getEncoder().encodeToString(htmlBytes));
CompletableFuture<CompletableFuture<byte[]>> thenApply = CompletableFuture.supplyAsync(this::getPhantom, threadPool).thenApply(
worker -> worker.convert(htmlMessage).thenApply(
pdfMessage -> Base64.getDecoder().decode(pdfMessage.getEncodedContent())
)
);
}
Sotirios Delimanolis :
There's a bug in its documentation, but the CompletableFuture#thenCompose
family of methods is the equivalent of a flatMap
. Its declaration should also give you some clues
public <U> CompletableFuture<U> thenCompose(Function<? super T,? extends CompletionStage<U>> fn)
thenCompose
takes the result of the receiver CompletableFuture
(call it 1) and passes it to the Function
you provide, which must return its own CompletableFuture
(call it 2). The CompletableFuture
(call it 3) returned by thenCompose
will be completed when 2 completes.
In your example
CompletableFuture<Worker> one = CompletableFuture.supplyAsync(this::getPhantom, threadPool);
CompletableFuture<PdfMessage /* whatever */> two = one.thenCompose(worker -> worker.convert(htmlMessage));
CompletableFuture<byte[]> result = two.thenApply(pdfMessage -> Base64.getDecoder().decode(pdfMessage.getEncodedContent()));
Guess you like
Origin http://10.200.1.11:23101/article/api/json?id=448277&siteId=1