2017-02-21 90 views
1

我是新来的Java和正在使用CompletableFutures执行异步操作,如下面歇执行顺序:爪哇 - 使用CompletableFuture链

public CompletionStage<Either<ErrorResponse, Response>> insertOrUpdate(String actor, String key) { 
    return this.objectDAO.getByKey(key) 
      .thenApply(mapDOToContainer(key)) 
      .thenApply(mergeContainerToDO(key, actor)) 
      .thenComposeAsync(this.objectDAO.UpdateFn()) 
      .thenApply(DBResult::finished) 
      .thenApply(finished -> { 
       if (finished) { 
        Response response = Response.ok().build(); 
        return Either.right(response); 
       } else { 
        return Either.left(ErrorResponse.create("Error", 400)); 
       } 
      }); 
} 

现在我需要这样,如果GET失败,则我进行修改此上面的链,但如果它成功,那么我需要打破这个链,并从包含ErrorResponse的Either对象的函数返回。

我该如何打破这个加工链?我知道我可以给链中的每个函数传递一个标志,并通过根据标志的值执行函数中的操作来实现这一点。我希望有更好的方法来做到这一点。

谢谢!

+0

一个例外会打破连锁。 CompletableFuture有特殊的方法来处理异常情况,我根本不会使用'Either'来返回错误,这是因为没有例外的语言。 – john16384

+0

您可以应用[Optional](https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html),如'Optional.of(objectDAO.getByKey(key))'。或者DAO的方法可以返回一个可选项,因为显然有一个选项,这个DAO没有找到关键字。重点是:[ifPresent](https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html#ifPresent-java.util.function.Consumer-)在这里派上用场。 –

回答

0

我会重写你的代码。

  • 不要使用要么错误,Java有例外
  • 不要从你的DAO
  • 使用exceptionally从CompletableFuture,它是专为这个

然后做返回CompletionStage这样的:

public CompletionStage<Response> insertOrUpdate(String actor, String key) { 
    return CompletableFuture.supplyAsync(() -> this.objectDAO.getByKey(key)) 
      .thenApply(mapDOToContainer(key)) 
      .thenApply(mergeContainerToDO(key, actor)) 
      .thenComposeAsync(this.objectDAO.UpdateFn()) 
      .thenApply(DBResult::finished) 
      .thenApply(finished -> { 
       Response response = Response.ok().build(); 
       return response; 
      }) 
      .exceptionally(e -> ErrorResponse.create("Error", 400)); 
} 

的DAO应该是这样的:

class ObjectDAO { 
    public Object getByKey(String key) { 
     if (keyNotFound) { 
      throw new NoSuchElementException(); 
     } 

     return new Object(); 
    } 
} 

您可能需要确保ErrorResponse是响应的子类才能使其工作。

+0

谢谢!我对使用异常有点困惑,但这清除了它。 – Rohit