首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java短路CompletableFuture

Java短路CompletableFuture
EN

Stack Overflow用户
提问于 2018-02-03 01:33:09
回答 2查看 616关注 0票数 1

我正在尝试根据特定条件找到跳过CompletableFuture的方法。

例如

代码语言:javascript
复制
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);
}

实现这一目标的好方法是什么?

EN

回答 2

Stack Overflow用户

发布于 2018-02-03 01:43:22

我将准备一个与您在问题中使用的示例不同的示例,因为从读者的角度来看,您的代码的意图不是很清楚。

首先假设存在一个CompletableFuture<String>,它提供了一个星战角色的名字。

代码语言:javascript
复制
CompletableFuture<String> character = CompletableFuture.completedFuture("Luke");

现在,假设我有另外两个CompletableFuture,它们代表了我可能想要遵循的不同道路,这取决于第一个可完成的未来是否提供了一个绝地角色。

代码语言:javascript
复制
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的概念)。

现在,我转到我的异步链:

代码语言:javascript
复制
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方法。

票数 2
EN

Stack Overflow用户

发布于 2018-02-03 02:11:20

我不确定我是否理解了你的目标,但是你为什么不像你在评论中说的那样使用未来的链接呢?类似这样的东西,只是为了说明一下:

代码语言:javascript
复制
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之后的第二个调用,这显然是不可能的,因为你需要那个结果。重要的是,你是否跳过它对你来说并不重要,因为它是异步的,你不会阻塞等待结果。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48588002

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档