【问题标题】:CompletableFuture chaining resultsCompletableFuture 链接结果
【发布时间】:2016-05-17 00:29:06
【问题描述】:

我正在尝试将方法的调用/结果链接到下一个调用。我得到编译时错误 methodE 因为如果我无法从之前的调用中获取 objB 的引用。

如何将上一个调用的结果传递给下一个链?我完全误解了这个过程吗?

Object objC = CompletableFuture.supplyAsync(() -> service.methodA(obj, width, height))
    .thenApply(objA -> {
    try {
        return service.methodB(objA);
    } catch (Exception e) {
        throw new CompletionException(e);
    }
})
   .thenApply(objA -> service.methodC(objA))
   .thenApply(objA -> {
   try {
       return service.methodD(objA); // this returns new objB how do I get it and pass to next chaining call 
       } catch (Exception e) {
           throw new CompletionException(e);
       }
    })
    .thenApply((objA, objB) -> {
       return service.methodE(objA, objB); // compilation error 
  })
 .get();

【问题讨论】:

  • 你可能会让你的第一个 thenApply 返回一个元组来保存 objA 和方法 B 的结果。或者,由于您使用的是 thenApply 而不是 thenApplyAsync,因此将连续的 thenApply 调用合并到一个 lambda 中在功能上是等效的,并为您提供所需的灵活性
  • 顺便说一句,由于您使用的是CompletableFuture(或CompletionStage),我会用一个完成(例如通过whenComplete(...)handle(...))替换handle(...),这将执行最后一步,例如,为 UI 执行器安排未来或在 Web 服务中生成并返回 DTO(成功或异常时,报告错误)。与 Java 未来必须提供的任何其他东西相比,避免阻塞通常是最好的“投资”(尽管其他一切也很有用)。

标签: java java-8 completable-future


【解决方案1】:

您应该使用 thenCompose,它是一种异步映射,而不是 thenApply,它是同步的。这是一个链接两个未来返回函数的示例:

public CompletableFuture<String> getStringAsync() {
    return this.getIntegerAsync().thenCompose(intValue -> {
        return this.getStringAsync(intValue);
    });
}

public CompletableFuture<Integer> getIntegerAsync() {
    return CompletableFuture.completedFuture(Integer.valueOf(1));
}

public CompletableFuture<String> getStringAsync(Integer intValue) {
    return CompletableFuture.completedFuture(String.valueOf(intValue));
}

使用 thenApply 您不会返回未来。使用 thenCompose,您可以做到。

【讨论】:

    【解决方案2】:

    您可以将中间的CompletableFuture 存储在一个变量中,然后使用thenCombine

    CompletableFuture<ClassA> futureA = CompletableFuture.supplyAsync(...)
        .thenApply(...)
        .thenApply(...);
    
    CompletableFuture<ClassB> futureB = futureA.thenApply(...);
    
    CompletableFuture<ClassC> futureC = futureA.thenCombine(futureB, service::methodE);
    
    objC = futureC.join();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-01-04
      • 1970-01-01
      • 1970-01-01
      • 2022-11-01
      • 2019-07-22
      • 2015-07-19
      • 1970-01-01
      • 2017-09-09
      相关资源
      最近更新 更多