将 CompletableFuture 链接到 return 第一个值
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
方法中 return void
。我想 return 一个 MyEntity
所以我尝试了:
private CompletableFuture<MyEntity> save(MyEntity me) {
CompletableFuture<MyEntity> future = ContextAwareCompletableFuture
.runAsync(() -> repository.save(me))
.thenRunAsync(() -> foo(me))
.thenRunAsync(() -> bar(me));
return future;
}
这不起作用,因为 runAsync
return 无效。我的方法 repository.save()
return 是我希望 return 的对象,但该调用位于链的开头。我需要先保存对象,然后才能执行 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
正确完成后 return 保存在 repository.save()
中的对象?
你可以链接一个做东西的方法和returns输入:
.thenApply(e -> { foo(e); return e; }
如果 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
。最后我也躲过了被抓
如果我们 return fooFuture
和 barFuture
上的实体,我们可以避免一个 thenCombine
:
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);
}
我有一些代码使用 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
方法中 return void
。我想 return 一个 MyEntity
所以我尝试了:
private CompletableFuture<MyEntity> save(MyEntity me) {
CompletableFuture<MyEntity> future = ContextAwareCompletableFuture
.runAsync(() -> repository.save(me))
.thenRunAsync(() -> foo(me))
.thenRunAsync(() -> bar(me));
return future;
}
这不起作用,因为 runAsync
return 无效。我的方法 repository.save()
return 是我希望 return 的对象,但该调用位于链的开头。我需要先保存对象,然后才能执行 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
正确完成后 return 保存在 repository.save()
中的对象?
你可以链接一个做东西的方法和returns输入:
.thenApply(e -> { foo(e); return e; }
如果 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
。最后我也躲过了被抓
如果我们 return fooFuture
和 barFuture
上的实体,我们可以避免一个 thenCombine
:
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);
}