Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is CompletableFuture's equivalent of flatMap?

Tags:

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())         )     );  } 
like image 691
Rico Kahler Avatar asked Aug 10 '16 23:08

Rico Kahler


People also ask

What is difference between thenApply and thenCompose?

thenCompose() is better for chaining CompletableFuture. thenApply() is better for transform result of Completable future. You can achieve your goal using both techniques, but one is more suitable for one use case then other.

How CompletableFuture is non-blocking?

CompletableFuture is used for asynchronous programming in Java. Asynchronous programming is a means of writing non-blocking code by running a task on a separate thread than the main application thread and notifying the main thread about its progress, completion or failure.

What does CompletableFuture runAsync do?

runAsync. Returns a new CompletableFuture that is asynchronously completed by a task running in the given executor after it runs the given action.

What is the difference between future and CompletableFuture?

Future transferes single value using synchronous interface. CompletableFuture transferes single value using both synchronous and asynchronous interfaces. Rx transferes multiple values using asynchronous interface with backpressure.


1 Answers

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())); 
like image 137
Sotirios Delimanolis Avatar answered Sep 28 '22 02:09

Sotirios Delimanolis