[英]Chaining stream of CompletableFuture or chaining CompletableFuture?
[英]Chaining in CompletableFuture to return first value
我有一些代码可以使用spring-data
将实体保存到数据库,然后执行其他一些工作foo()
和bar()
,这些工作需要已保存的实体的id
。 看起来像这样:
private CompletableFuture<Void> save(MyEntity me) {
CompletableFuture<Void> future = ContextAwareCompletableFuture
.runAsync(() -> repository.save(me))
.thenRunAsync(() -> foo(me))
.thenRunAsync(() -> bar(me));
return future;
}
private Foo foo(MyEntitiy me) {
// Use the identifier for me to update some foo in another world
}
private Bar bar(MyEntitiy me) {
// Use the identifier for me to update some bar in at another time
}
现在,我不想从我的save
方法返回void
。 我想返回一个MyEntity
所以我尝试了:
private CompletableFuture<MyEntity> save(MyEntity me) {
CompletableFuture<MyEntity> future = ContextAwareCompletableFuture
.runAsync(() -> repository.save(me))
.thenRunAsync(() -> foo(me))
.thenRunAsync(() -> bar(me));
return future;
}
这不起作用,因为runAsync
返回void。 我的方法repository.save()
返回了我希望返回的对象,但是该调用位于链的开头。 我需要先保存对象,然后才能执行foo
和bar
。
所以我接下来尝试的是:
private CompletableFuture<MyEntity> save(MyEntity me) {
CompletableFuture<MyEntity> future = ContextAwareCompletableFuture
.supplyAsync(() -> repository.save(me))
.thenApplyAsync((e) -> baz(e);
return future;
}
private MyEntity baz(MyEntitiy me) {
foo(me);
bar(me);
return me;
}
现在,这对我来说似乎是错误的。 Foo
和Bar
现在必须在同一阶段执行,这可能需要一些时间。
在foo
和bar
正确完成后,如何返回保存在repository.save()
的对象?
如果foo
和bar
可以同时运行,则可以选择在save
而不是对其进行排序:
private CompletableFuture<MyEntity> save(MyEntity me) {
CompletableFuture<MyEntity> future = ContextAwareCompletableFuture
.supplyAsync(() -> repository.save(me));
CompletableFuture<Void> fooFuture = future
.thenAcceptAsync((e) -> foo(e));
CompletableFuture<Void> barFuture = future
.thenAcceptAsync((e) -> bar(e));
return future
.thenCombine(fooFuture, (result, fooResult) -> result)
.thenCombine(barFuture, (result, barResult) -> result);
}
请注意,我使用thenAcceptAsync
而不是thenRunAsync
来避免捕获me
。 最后我也避免了被捕获。
我们能避免一个thenCombine
如果我们回到对实体fooFuture
和barFuture
:
private CompletableFuture<MyEntity> save(MyEntity me) {
CompletableFuture<MyEntity> future = ContextAwareCompletableFuture
.supplyAsync(() -> repository.save(me));
CompletableFuture<MyEntity> fooFuture = future
.thenApplyAsync((e) -> { foo(e); return e; });
CompletableFuture<MyEntity> barFuture = future
.thenApplyAsync((e) -> { bar(e); return e; });
return fooFuture
.thenCombine(barFuture, (fooResult, barResult) -> fooResult);
}
您可以使用一个可以填充并返回输入的方法进行链接:
.thenApply(e -> { foo(e); return e; }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.