本文介绍了如何组合 3 个或更多 CompletionStages?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果有 2 个 CompletionStages,我可以将它们与 thenCombine 方法结合起来:

If have 2 CompletionStages, I can combine them with thenCombine method:

CompletionStage<A> aCompletionStage = getA();
CompletionStage<B> bCompletionStage = getB();
CompletionStage<Combined> combinedCompletionStage =
    aCompletionStage.thenCombine(bCompletionStage, (aData, bData) -> combine(aData, bData));

如果我有 3 个或更多 CompletionStages,我可以创建一个 thenCombine 方法链,但我必须使用临时对象来传递结果.例如,这是一个使用 org.apache.commons.lang3.tuple 包中的 PairTriple 的解决方案:

If I have 3 or more CompletionStages, I can make a chain of thenCombine methods, but I have to use temporary objects to pass results. For example, here is a solution using Pair and Triple from the org.apache.commons.lang3.tuple package:

CompletionStage<A> aCompletionStage = getA();
CompletionStage<B> bCompletionStage = getB();
CompletionStage<C> cCompletionStage = getC();
CompletionStage<D> dCompletionStage = getD();

CompletionStage<Combined> combinedDataCompletionStage =
        aCompletionStage.thenCombine(bCompletionStage, (Pair::of))
                .thenCombine(cCompletionStage, (ab, c) ->
                        Triple.of(ab.getLeft(), ab.getRight(), c))
                .thenCombine(dCompletionStage, (abc, d) ->
                        combine(abc.getLeft(), abc.getMiddle(), abc.getRight(), d));

是否有更好的方法来组合多个 CompletionStages 的结果?

Is there a better way to combine results from multiple CompletionStages?

推荐答案

结合多个阶段的唯一方法是使用 CompletableFuture.如果你的 CompletionStage 不是 CompletableFuture 你仍然可以使用 .toCompletableFuture() 转换它们:

The only way to combine multiple stages that scales well with a growing number of stages, is to use CompletableFuture. If your CompletionStages aren’t CompletableFutures you may still convert them using .toCompletableFuture():

CompletableFuture<A> aCompletionStage = getA().toCompletableFuture();
CompletableFuture<B> bCompletionStage = getB().toCompletableFuture();
CompletableFuture<C> cCompletionStage = getC().toCompletableFuture();
CompletableFuture<D> dCompletionStage = getD().toCompletableFuture();

CompletionStage<Combined> combinedDataCompletionStage = CompletableFuture.allOf(
    aCompletionStage, bCompletionStage, cCompletionStage, dCompletionStage)
    .thenApply(ignoredVoid -> combine(
        aCompletionStage.join(), bCompletionStage.join(),
        cCompletionStage.join(), dCompletionStage.join()) );

这包含比通过 thenCombine 组合两个阶段更多的样板,但在向其中添加更多阶段时样板不会增长.

This contains more boilerplate than combining two stages via thenCombine but the boilerplate doesn’t grow when adding more stages to it.

请注意,即使使用原始的 thenCombine 方法,您也不需要 Triple,一个 Pair 就足够了:

Note that even with your original thenCombine approach, you don’t need a Triple, a Pair is sufficient:

CompletionStage<Combined> combinedDataCompletionStage =
    aCompletionStage.thenCombine(bCompletionStage, (Pair::of)).thenCombine(
        cCompletionStage.thenCombine(dCompletionStage, Pair::of),
        (ab, cd) -> combine(ab.getLeft(), ab.getRight(), cd.getLeft(), cd.getRight()));

不过,如果您想组合更多阶段,它的扩展性并不好.

Still, it doesn’t scale well if you want to combine more stages.

中间解决方案(关于复杂性)可能是:

An in-between solution (regarding complexity) might be:

CompletionStage<Combined> combinedDataCompletionStage = aCompletionStage.thenCompose(
    a -> bCompletionStage.thenCompose(b -> cCompletionStage.thenCompose(
        c -> dCompletionStage.thenApply(d -> combine(a, b, c, d)))));

它的结构更简单,但仍然不能很好地扩展更多阶段.

That’s simpler in its structure but still doesn’t scale well with more more stages.

这篇关于如何组合 3 个或更多 CompletionStages?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-27 21:50