web-dev-qa-db-ja.com

CompletableFutureのflatMapに相当するものは何ですか?

私はこの奇妙なタイプを持っています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())
        )
    );

}
18
Rico Kahler

ドキュメントには 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()));
23