【问题标题】:Converting blocking code to non-blocking when early returns are involved涉及提前返回时将阻塞代码转换为非阻塞代码
【发布时间】:2018-03-14 22:52:25
【问题描述】:

我正在尝试转换如下所示的阻塞 Play 框架控制器操作:

public Result testSync(String param1, String param2) {

    String result1 = <LONG-DB-QUERY>;
    if (result1 == null) {
        return internalServerError();
    }

    if (result1.equals("<SOME VALUE>")) {
        return ok(param1);
    }

    String result2 = <LONG-DB-QUERY>;
    return ok(result1 + result2);
}

使用Future接口进入非阻塞代码,即返回一个CompletionStage&lt;Result&gt;

如您所见,我需要result1result2。我假设我不能使用supplyAsyncthenCombine,因为result2 只有在某些情况下才需要计算。

【问题讨论】:

  • 为什么不把整个东西包装成supplyAsync()

标签: java-8 playframework-2.0 nonblocking completable-future completion-stage


【解决方案1】:

好的,基于similar answer,我就是这样做的:

public CompletionStage<Result> testAsync(String param1, String param2) {

    CompletableFuture<Result> shortCut = new CompletableFuture<>();
    CompletableFuture<String> withChain = new CompletableFuture<>();

    CompletableFuture.runAsync(() -> {
        String result1 = <LONG-DB-QUERY>;
        if (result1 == null) {
            shortCut.complete(internalServerError());
            return;
        }

        if (result1.equals("<SOME VALUE>")) {
            shortCut.complete(ok(param1));
            return;
        }

        withChain.complete(result1);
    });

    return withChain
            .thenCombine(CompletableFuture.supplyAsync(() -> <LONG-DB-QUERY>), (newParam1, newParam2) -> ok(result1+result2))
            .applyToEither(shortCut, Function.identity());
}

【讨论】:

  • 使用此解决方案,即使您不使用它的结果,您也始终会计算 result2。此外,这两个查询是并行运行的,因此您实际上可能会得到第二个查询而不是第一个查询的结果,如果它更快的话——这是有意的吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-01-18
  • 2020-05-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-25
  • 2023-03-12
相关资源
最近更新 更多