私はこの奇妙なタイプを持っています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())
)
);
}
ドキュメントには bug がありますが、 CompletableFuture#thenCompose
メソッドのファミリーはflatMap
と同等です。その宣言はまたあなたにいくつかの手がかりを与えるはずです
public <U> CompletableFuture<U> thenCompose(Function<? super T,? extends CompletionStage<U>> fn)
thenCompose
はレシーバーCompletableFuture
の結果を受け取り(それを1と呼びます)、それをFunction
提供し、独自のCompletableFuture
を返す必要があります(2と呼びます)。 CompletableFuture
によって返されるthenCompose
(call it3)は、2が完了します。
あなたの例では
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()));