CompletableFuture 与 flatMap 的等价物是什么?

What is CompletableFuture's equivalent of 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())
        )
    );

}

有一个 bug in its documentation, but the CompletableFuture#thenCompose 系列方法等同于一个 flatMap。它的声明也应该给你一些线索

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

thenCompose 获取接收器 CompletableFuture 的结果(称之为 1)并将其传递给您提供的 Function,它必须 return 它自己的 CompletableFuture(称之为 2)。由 thenCompose 编写的 CompletableFuture(称为 3)return 将在 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()));