2016-08-10 2 views
6

J'ai ce type bizarre CompletableFuture<CompletableFuture<byte[]>> mais je veux CompletableFuture<byte[]>. Est-ce possible?Quel est l'équivalent de FlatMap de CompletableFuture?

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()) 
     ) 
    ); 

} 

Répondre

8

Il y a un bug dans sa documentation, mais la famille CompletableFuture#thenCompose des méthodes est l'équivalent d'un flatMap. Sa déclaration devrait également vous donner quelques indices

public <U> CompletableFuture<U> thenCompose(Function<? super T,? extends CompletionStage<U>> fn) 

thenCompose prend le résultat du récepteur CompletableFuture (appeler) et passe à la Function que vous fournissez, qui doit retourner son propre CompletableFuture (appeler). Le CompletableFuture (appelez-le) retourné par thenCompose sera complété lorsque sera complété.

Dans votre exemple

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()));