Java CompletableFuture:避免回调地狱

时间:2016-11-19 12:09:29

标签: java akka completable-future

我对Java中的CompletableFuture有疑问。我等待CompletableFuture完成,并根据收到的结果,我想要调用一个新任务并等待CompletableFuture完成或做一些不同的事情。我对我的解决方案不满意,因为有太多的回调,并且阅读不同。你能帮助我改进我的代码吗?

final CompletableFuture<String> future = new CompletableFuture<>();

final ActorRef processCheckActor = actorSystem.actorOf(
    springExtension.props("ProcessCheckActor"), "processCheckActor-" + new Random().nextInt());

final CompletableFuture<Object> checkResponse =
    PatternsCS.ask(processCheckActor, new ProcessToCheckMessage(processId), TIMEOUT)
        .toCompletableFuture();

checkResponse.thenAccept(obj -> {
  final ProcessCheckResponseMessage msg = (ProcessCheckResponseMessage) obj;
  if (msg.isCorrect()) {
    final CompletableFuture<Object> response =
        PatternsCS.ask(processSupervisorActor, new ProcessStartMessage(processId), TIMEOUT)
            .toCompletableFuture();

    response.thenAccept(obj2 -> {
      future.complete("yes");
    });
  } else {
    future.complete("no");
  }
});

2 个答案:

答案 0 :(得分:2)

首先,您应该避免创建CompletableFuture<Object>。泛型类型应该是函数返回的类型(在您的情况下为CompletableFuture<ProcessCheckResponseMessage>)。这样你就不需要演员了。

我建议使用thenApply而不是thenAccept。这将为您创建第二个CompletableFuture,这意味着您不再需要第一行中的声明。

最后,作为一般规则,你应该三思而后行多线lambda,并且绝对避免嵌套的lambdas。您应该考虑为这些lambda创建一个新方法。

答案 1 :(得分:1)

我的2美分示例代码可以帮助您回调场景。

我写了3个函数:public function destroy(Account $account) { $findAccount = Account::findOrFail($account->id); ... } testFunctiongetResponseMessage

  • getResponseString是主要功能。
  • testFunction通过getResponseMessage
  • 链接到主testFunction
  • thenApply最后通过getResponseString链接。

诀窍是通过高阶函数链接多个较小的函数,如thenComposethenApplythenCompose等。

thenCombine