2016-08-10 67 views
6

我有這個奇怪的類型CompletableFuture<CompletableFuture<byte[]>>,但我想CompletableFuture<byte[]>。這可能嗎?什麼是CompletableFuture相當於flatMap的功能?

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

} 

回答

8

有它的文檔在bug,但CompletableFuture#thenCompose家庭的方法是flatMap的等價物。它的聲明也應該給你一些線索

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

thenCompose需要接收CompletableFuture的結果(稱之爲),並把它傳遞給Function您提供的,它必須返回自己的CompletableFuture(稱之爲)。所述CompletableFuture(稱之爲)由thenCompose返回將被當完成完成。

在您的例子

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