代码之家  ›  专栏  ›  技术社区  ›  Hearen

completeFuture句柄和completeExceptionally不能一起工作?

  •  2
  • Hearen  · 技术社区  · 8 年前

    我正试图设置一个 违约 异常发生时的值 CompletableFuture 我让它工作 handle 方法如下:

    private static void testHandle() {
        String name = null;
        CompletableFuture<String> completableFuture
                = CompletableFuture.supplyAsync(() -> {
            if (name == null) {
                throw new RuntimeException("Computation error!");
            }
            return "Hello, " + name;
        }).handle((s, t) -> s != null ? s : "Hello, Stranger!" + t.toString());
        out.println(completableFuture.join());
    }
    

    但当我试图阻止 复杂的未来 使用 completeExceptionally 当坏事情发生并跟踪 例外 如下我不明白 例外 就像我刚才做的。

    private static void testCompleteExceptionally() {
        String name = "Hearen";
        CompletableFuture<String> completableFuture
                = CompletableFuture.supplyAsync(() -> {
            delay(500L);
            if (name == null) {
                throw new RuntimeException("Computation error!");
            }
            return "Hello, " + name;
        }).handle((s, t) -> {
            try {
                throw t.getCause(); 
            } catch (Throwable e) {
                out.println(e.toString()); // I was hoping to record the custom exceptions here;
            }
            return s != null ? s : "Hello, Stranger!" + t.toString();
        });
    
        if (name != null) {
            completableFuture.completeExceptionally(new RuntimeException("Calculation failed!")); // when bad things happen, I try to complete it by exception;
        }
        out.println(completableFuture.join());
    
    }
    

    更新 2018-06-09谢谢你的帮助,@daniele

    private static void testCompleteExceptionally() {
        String name = "Hearen";
        CompletableFuture<String> completableFuture
                = CompletableFuture.supplyAsync(() -> {
            delay(500L);
            if (name == null) {
                throw new RuntimeException("Computation error!");
            }
            return "Hello, " + name;
        });
    
        if (name != null) {
            completableFuture.completeExceptionally(new RuntimeException("Calculation failed!"));
        }
        out.println(completableFuture.handle((s, t) ->  s != null ? s : "Hello, Stranger!" + t.toString()).join());
    
    }
    

    这个 手柄 前附 join() 按预期工作。但在这种情况下, returned value null .

    基于 handle API

    返回 新的 CompletionStage,当此阶段正常或异常完成时,使用此阶段的结果和异常作为所提供函数的参数执行。

    1 回复  |  直到 8 年前
        1
  •  0
  •   Daniele    8 年前

    future handle

    package stackOv;
    
    import java.util.concurrent.CompletableFuture;
    import java.util.function.BiFunction;
    import java.util.function.Supplier;
    
    public class TestHandle {
      BiFunction<String, Throwable, String> handle2 = new BiFunction<String, Throwable, String>() {
        @Override
        public String apply(String s, Throwable t) {
          try {
            throw t.getCause(); 
          } catch (Throwable e) {
            // I was hoping to record the custom exceptions here;
            System.out.println(e.toString());
          }
          return s != null ? s : "Hello, Stranger!" + t.toString();
        }
      };
    
      private void testCompleteExceptionally() {
        String name = "Hearen";
        Supplier<String> supplier2 = () -> {
          delay(500L);
          if (name == null) {
            throw new RuntimeException("Computation error!");
          }
          return "Hello, " + name;
        };
        CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(supplier2);
    
        if (name != null) {
          // when bad things happen, I try to complete it by exception;
          completableFuture.completeExceptionally(new RuntimeException("Calculation failed!"));      
        }
        System.out.println(completableFuture.handle(handle2).join());
      }
    
      public static void main(String[] args) {
        TestHandle th = new TestHandle();
        th.testCompleteExceptionally();
      }
    
      private static void delay(long milli) {
        try { Thread.sleep(milli); } catch (InterruptedException e) {}    
      }
    }