我正在尝试根据具体情况找到跳过CompletableFuture的方法。
例如
public CompletableFuture<Void> delete(Long id) {
CompletableFuture<T> preFetchCf = get(id);
CompletableFuture<Boolean> cf1 = execute();
/*This is where I want different execution path, if result of this future is true go further, else do not*/
// Execute this only if result of cf1 is true
CompletableFuture<T> deleteCf = _delete(id);
// Execute this only if result of cf1 is true
CompletableFuture<T> postDeleteProcess = postDelete(id);
}
实现这一目标的好方法是什么?
答案 0 :(得分:1)
我将准备一个与您在问题中使用的示例不同的示例,因为从读者的角度来看,您的代码的意图并不十分明确。
首先假设现有的CompletableFuture<String>
提供星球大战角色的名称。
CompletableFuture<String> character = CompletableFuture.completedFuture("Luke");
现在,想象一下我还有另外两个CompletableFuture
代表我可能想要遵循的不同路径,这取决于第一个可完成的未来是否提供了一个绝地角色。
Supplier<CompletableFuture<String>> thunk1 = () -> CompletableFuture.completedFuture("This guy is a Jedi");
Supplier<CompletableFuture<String>> thunk2 = () -> CompletableFuture.completedFuture("This guy is not a Jedi");
请注意,我将CompletableFuture
包裹在一个Supplier
中,以避免他们急切地评估(这是thunk这个概念)。
现在,我去了我的异步链:
character.thenApply(c -> isJedi(c))
.thenCompose(isJedi -> isJedi ? thunk1.get() : thunk2.get())
.whenComplete((answer, error) -> System.out.println(answer));
使用thenCompose
让我根据布尔结果选择路径。在那里,我评估其中一个thunk并使其为我关心的路径创建一个新的CompletableFuture
。
这将打印到屏幕"This guys is a Jedi"
。
所以,我相信你要找的是thenCompose
方法。
答案 1 :(得分:0)
不确定我是否理解你的目标,但为什么你不会像你在评论中所说的那样选择未来的链接?这样的事情,只是为了说明:
public class AppTest {
@Test
public void testCompletableFutures() {
Integer id = (int) Math.random() * 1000;
CompletableFuture<Void> testing = AppTest.execute()
.thenAcceptAsync(result -> {
System.out.println("Result is: " + result);
if(result)
AppTest.delete(id);
else
throw new RuntimeException("Execution failed");
})
.thenApplyAsync(result -> AppTest.postDelete())
.thenAcceptAsync(postDeleteResult -> {
if(postDeleteResult)
System.out.println("Post delete cleanup success");
else
throw new RuntimeException("Post delete failed");
});
}
private static boolean postDelete() {
System.out.println("Post delete cleanup");
return Math.random() > 0.3;
}
private static CompletableFuture<Boolean> delete(int i) {
System.out.println("Deleting id = " + i);
return CompletableFuture.completedFuture(true);
}
private static CompletableFuture<Boolean> execute() {
return CompletableFuture.supplyAsync(() -> Math.random() > 0.5);
}
}
当然,这并没有太多的现实意义,但我认为这有助于展示一个概念。
如果你想根据结果跳过execute
之后的第二个电话,那么显然不可能,因为你需要那个结果。关键在于你是否跳过它并不重要,因为它是异步的,你不会阻止等待那个结果。