根据某些条件停止/完成循环的CompletableFuture

CompletableFuture<String> future = CompletableFuture.completedFuture(null);
for(int _retrial = 1 ; _retrial <= getRetrialCountBasedOnSomeLogic() ; _retrial++) {
  int finalRetrial = _retrial;
  future = future
      .thenCompose(lastRetrialStatus -> {
        if(Strings.isnullOrEmpty(lastRetrialStatus) || (!"SUCCESS".equals(lastRetrialStatus))) {
          return doSomeCalculations(finalRetrial);
        } else {
          return CompletableFuture.completedFuture(null);
        }
      })
      .handle((response,throwable) -> {
        if(throwable != null) {
          throwable = CompletableFutures.unwrapCompletionStateException(throwable);
          return throwable.getMessage();
        }
        return "SUCCESS";
      });
}
return future;

我最近开始在上面的代码中从事completablefutures的工作-如您所见,我正在用for循环链接期货。如果句柄返回“ SUCCESS”,我希望链停止。像这样:

CompletableFuture<String> future = CompletableFuture.completedFuture(null);
for(int _retrial = 1 ; _retrial <= getRetrialCountBasedOnSomeLogic() ; _retrial++) {
  int finalRetrial = _retrial;
  future = future
      .thenCompose(lastRetrialStatus -> doSomeCalculations(finalRetrial))
      .handle((response,throwable) -> {
        if(throwable != null) {
          throwable = CompletableFutures.unwrapCompletionStateException(throwable);
          return throwable.getMessage();
        }
        **Its a success,I dont need to look for any further passes of this loop. Lets end here by returning "SUCCESS"**
      });
}
return future;
ttzzhhssjjnn 回答:根据某些条件停止/完成循环的CompletableFuture

仅使重试动作链接成为处理程序的一部分,该处理程序仅在知道成功状态时才执行。由于通过lambda表达式定义的函数无法引用自身,因此您需要一种可以调用的方法,例如

static CompletableFuture<String> yourMethod() {
    return yourMethod(1,getRetrialCountBasedOnSomeLogic());
}

private static CompletableFuture<String> yourMethod(int currentTry,int maxTries) {
    CompletableFuture<String> future = doSomeCalculations(currentTry);
    int nextTry = currentTry + 1;
    return future
        .handle((s,t) -> t == null? CompletableFuture.completedFuture("SUCCESS"):
            nextTry <= maxTries? yourMethod(nextTry,maxTries):
            CompletableFuture.completedFuture(
                CompletableFutures.unwrapCompletionStateException(t).getMessage()))
        .thenCompose(Function.identity());
}

不幸的是,handle没有映射到另一个未来的变体,因此我们需要先映射到.thenCompose(Function.identity())之后的未来的未来

您可以通过有条件地链接不同的阶段来略微减少最后一次不需要合成的工作:

private static CompletableFuture<String> yourMethod(int currentTry,int maxTries) {
    CompletableFuture<String> future
        = doSomeCalculations(currentTry).thenApply(x -> "SUCCESS");
    int nextTry = currentTry + 1;
    return nextTry <= maxTries?
        future.thenApply(CompletableFuture::completedFuture)
            .exceptionally(t -> yourMethod(nextTry,maxTries))
            .thenCompose(Function.identity()):
        future.exceptionally(t ->
            CompletableFutures.unwrapCompletionStateException(t).getMessage());
}

如果maxTries不是常数,但需要像循环那样重新评估getRetrialCountBasedOnSomeLogic(),则此变体也可以使用:

static CompletableFuture<String> yourMethod() {
    return yourMethod(1);
}

static CompletableFuture<String> yourMethod(int currentTry) {
    int maxTries = getRetrialCountBasedOnSomeLogic();
    CompletableFuture<String> future
        = doSomeCalculations(currentTry).thenApply(x -> "SUCCESS");
    int nextTry = currentTry + 1;
    return nextTry <= maxTries?
        future.thenApply(CompletableFuture::completedFuture)
            .exceptionally(t -> yourMethod(nextTry))
            .thenCompose(Function.identity()):
        future.exceptionally(t ->
            CompletableFutures.unwrapCompletionStateException(t).getMessage());
}
本文链接:https://www.f2er.com/3060414.html

大家都在问