如何访问 CompletableFuture 链中所有先前的 CompletionStage 结果
How to access all previous CompletionStage results in CompletableFuture chain
我在 Java 8 应用程序中工作。我有 3 种方法 return CompletionStage:
CompletionStage<Edition> editionService.loadById(editionId);
CompletionStage<Event> eventService.loadById(eventId);
CompletionStage<List<EditionDate>> editionDateService.loadByEditionId(editionId);
以及将这些值合并为结果的方法
CompletionStage<Result> getResult(Edition edition, Event event, List<EditionDate> editionDates)
方法一和方法三可以独立运行,但是方法二的调用依赖于方法一的结果,显然方法四依赖于所有的方法运行。我的问题是,使用 CompletableFuture api 调用这些方法的最佳方式是什么?这是我能想到的最好方法,但我不确定这是最好的方法:
editionService.loadById(editionId)
.thenCompose(edition -> eventService.loadById(edition.getEventId()))
.thenCombine(editionDateService.loadByEditionId(editionId),
(event, editionDates) -> getResult(edition, event, editionDates) );
但是这样我就无法访问我的 edition
结果,所以我有点不知所措。我应该使用哪些我没有考虑到的方法?
最简单的解决方案是在活动中提供版本。或者将对 2 的调用包装在另一个方法中 return pair(edition, event) instead
在我看来,类似以下代码的东西看起来不错,但无法仅使用您的那段代码对其进行测试,因此您需要对其进行测试并使其更清晰。这只是概念证明:)
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) );
}
你可以写成
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());
我在 Java 8 应用程序中工作。我有 3 种方法 return CompletionStage:
CompletionStage<Edition> editionService.loadById(editionId);
CompletionStage<Event> eventService.loadById(eventId);
CompletionStage<List<EditionDate>> editionDateService.loadByEditionId(editionId);
以及将这些值合并为结果的方法
CompletionStage<Result> getResult(Edition edition, Event event, List<EditionDate> editionDates)
方法一和方法三可以独立运行,但是方法二的调用依赖于方法一的结果,显然方法四依赖于所有的方法运行。我的问题是,使用 CompletableFuture api 调用这些方法的最佳方式是什么?这是我能想到的最好方法,但我不确定这是最好的方法:
editionService.loadById(editionId)
.thenCompose(edition -> eventService.loadById(edition.getEventId()))
.thenCombine(editionDateService.loadByEditionId(editionId),
(event, editionDates) -> getResult(edition, event, editionDates) );
但是这样我就无法访问我的 edition
结果,所以我有点不知所措。我应该使用哪些我没有考虑到的方法?
最简单的解决方案是在活动中提供版本。或者将对 2 的调用包装在另一个方法中 return pair(edition, event) instead
在我看来,类似以下代码的东西看起来不错,但无法仅使用您的那段代码对其进行测试,因此您需要对其进行测试并使其更清晰。这只是概念证明:)
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) );
}
你可以写成
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());