我正在尝试根据特定条件找到跳过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);
}实现这一目标的好方法是什么?
发布于 2018-02-03 01:43:22
我将准备一个与您在问题中使用的示例不同的示例,因为从读者的角度来看,您的代码的意图不是很清楚。
首先假设存在一个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的使用让我可以根据布尔结果选择路径。在那里,我评估了其中一个CompletableFuture,并使它为我所关心的路径创建了一个新的thunk。
这将打印到屏幕"This guys is a Jedi"。
所以,我相信您正在寻找的是thenCompose方法。
发布于 2018-02-03 02:11:20
我不确定我是否理解了你的目标,但是你为什么不像你在评论中说的那样使用未来的链接呢?类似这样的东西,只是为了说明一下:
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之后的第二个调用,这显然是不可能的,因为你需要那个结果。重要的是,你是否跳过它对你来说并不重要,因为它是异步的,你不会阻塞等待结果。
https://stackoverflow.com/questions/48588002
复制相似问题