【问题标题】:CompletableFuture chaining with exception handling带有异常处理的 CompletableFuture 链接
【发布时间】:2018-08-31 17:59:19
【问题描述】:

我正在尝试编写一个步骤链,这样我就可以通过创建返回 CompletableFuture<Boolean> 的方法来避免 if 和 else 调用的大型嵌套链,例如......

client.connect(identifier).thenCompose(b -> client.authenticate())
                           .thenCompose(b -> client.sendSetting(settings))
                           .thenCompose(b -> client.saveSettings())
                           .thenCompose(b -> client.sendKey(key))
                           .thenCompose(b -> client.setBypassMode(true))
                           .thenCompose(b -> client.start())
                           .whenComplete((success, ex) -> {
                                 if(ex == null) {
                                     System.out.println("Yay");  
                                 } else {
                                     System.out.println("Nay");   
                                 }
                           });

如果客户端方法返回 CompletableFuture<Boolean> 决定是否继续处理必须在链中的每个 lambda 中完成,并且不提供在其中一个调用失败时提前中止的方法。我宁愿让调用返回 CompletableFuture<Void> 并使用 Exceptions 来控制是否 1) 执行链中的每个连续步骤和 2) 最终确定整个链是否成功。

我很难找到 CompletableFuture<Void> 上的哪个方法来交换 thenCompose 以使事情正常运行(更不用说编译了)。

【问题讨论】:

  • 还要注意我的调用链长度为 8 步。
  • 请发布真实的代码,很难弄清楚挑战是什么,甚至很难理解你真正想要实现的目标。
  • @ernest_k 感谢您的意见。希望这个问题的迭代更清楚。
  • 你在做异步操作吗? settings、key 是从哪里来的?它们是局部范围的变量吗?
  • 是的,每个客户端调用都需要通过串行端口进行 IO。是的,变量是局部作用域的。

标签: java completable-future


【解决方案1】:
public class FutureChaings {
    public static CompletableFuture<Void> op(boolean fail) {
        CompletableFuture<Void> future = new CompletableFuture<Void>();
        System.out.println("op");
        Executors.newScheduledThreadPool(1).schedule(() -> {
            if(fail) {
                future.completeExceptionally(new Exception());
            }
            future.complete(null);          
        }, 1, TimeUnit.SECONDS); 

        return future;
    }


    public static void main(String[] args) {
        op(false).thenCompose(b -> op(false)).thenCompose(b -> op(true)).whenComplete((b, ex) -> {
            if(ex != null) {
                System.out.println("fail");
            } else {
                System.out.println("success");
            }
        });
    }
}

我能够设计出一个按照我想要的方式运行的示例。所以我知道什么需要放在一起才能得到我想要的。现在要弄清楚编译器在我的真实代码中不喜欢什么。感谢 cmets。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-29
    • 2013-03-18
    • 1970-01-01
    • 2018-06-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多