如何在CompletableFuture链中访问所有先前的CompletionStage结果

问题描述 投票:2回答:2

我正在使用Java 8应用程序。我有3个返回CompletionStage的方法:

  1. CompletionStage<Edition> editionService.loadById(editionId);
  2. CompletionStage<Event> eventService.loadById(eventId);
  3. CompletionStage<List<EditionDate>> editionDateService.loadByEditionId(editionId);

以及将这些值合并到Result中的方法

  1. CompletionStage<Result> getResult(Edition edition, Event event, List<EditionDate> editionDates)

方法1和3可以独立运行,但调用方法2取决于方法1的结果。显然,方法4取决于它们的全部运行。我的问题是,使用CompletableFuture api调用这些方法的最佳方法是什么?这是我能想到的最好的但我不确定这是最好的方法:

editionService.loadById(editionId)
  .thenCompose(edition -> eventService.loadById(edition.getEventId()))
  .thenCombine(editionDateService.loadByEditionId(editionId), 
              (event, editionDates) -> getResult(edition, event, editionDates) );

但是这样我就无法访问我的edition结果,所以我有点不知所措。我应该使用的任何方法,我没有考虑到?

java completable-future
2个回答
2
投票

你可以把它写成

CompletionStage<Result> result = editionService.loadById(editionId)
    .thenCompose(edition -> eventService.loadById(edition.getEventId())
        .thenCombine(editionDateService.loadByEditionId(editionId),
            (event, editionDates) -> getResult(edition, event, editionDates) ) )
    .thenCompose(Function.identity());

但是,editionDateService.loadByEditionId将在editionService.loadById完成后触发,这是一种不必要的依赖。

最简单的解决方案是不要尝试将所有内容都写为单个表达式:

CompletionStage<List<EditionDate>> datesStage=editionDateService.loadByEditionId(editionId);
CompletionStage<Result> result = editionService.loadById(editionId)
    .thenCompose(edition -> eventService.loadById(edition.getEventId())
        .thenCombine(datesStage, (event, dates) -> getResult(edition, event, dates)) )
    .thenCompose(Function.identity());

1
投票

最简单的解决方案是在活动中提供版本。或者将2调用包含在anoher方法中,而该方法返回一对(版本,事件)

类似下面的代码对我来说看起来不错,但是不能仅用你的代码测试它,所以由你来测试它并使它更干净。这只是一个概念证明:)

public static class Pair{
        public Edition edition;
        public Event event;

        public Pair(Edition edition, Event event) {
            this.edition = edition;
            this.event = event;
        }
    }

    public static CompletionStage<Pair> wrap(Edition edition){
        CompletionStage<Event> event = eventService.loadById(edition.getEventId());
        return event.thenApply(ev -> new Pair(edition, ev));        
    }


    public static void main(String[] args) {
        int editionId = 42;


        editionService.loadById(editionId)
                .thenCompose(edition -> wrap(edition))
                .thenCombine(editionDateService.loadByEditionId(editionId),
                        (wrapped, editionDates) -> getResult(wrapped.edition, wrapped.event, editionDates) );
    }
© www.soinside.com 2019 - 2024. All rights reserved.