我有这种奇怪的类型CompletableFuture<CompletableFuture<byte[]>>
,但我想要CompletableFuture<byte[]>
。这可能吗?
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())
)
);
}
答案 0 :(得分:18)
其文档中有bug,但CompletableFuture#thenCompose
系列方法相当于flatMap
。它的声明还应该给你一些线索
public <U> CompletableFuture<U> thenCompose(Function<? super T,? extends CompletionStage<U>> fn)
thenCompose
获取接收者CompletableFuture
的结果(称之为 1 )并将其传递给您提供的Function
,其必须返回自己的CompletableFuture
{1}}(称之为 2 )。当 2 完成时,CompletableFuture
返回的thenCompose
(称为 3 )将会完成。
在你的例子中
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()));