无法逃避Scala中的嵌套未来?

时间:2017-03-09 18:10:31

标签: scala spray

我的Scala应用程序中有嵌套的未来。我知道必须始终有一条退出/返回方法的路径 - 而且我相信这会阻止这种嵌套的未来。

if (validRequest) {
  onComplete("a mongo query happens here") {
    case Success(result) =>
      if (result.isEmpty) {
        if (queryType.equals("id")) {
          onComplete("a different mongo query happens here") {
            case Success(result) =>
              complete(HttpResponse(200))
            case Failure(f) =>
              complete(HttpResponse(500))
          }
        }
      } else {
        complete(HttpResponse(200))
      }

    case Failure(f) =>
      complete(HttpResponse(500))
  }
} else {
  complete(HttpResponse(500))
}

以前,当这不支持运行单独的mongo查询时,它看起来如下;

onComplete("a mongo query") {
  case Success(result) =>
    complete(HttpResponse(200))
  case Failure(f) =>
    complete(HttpResponse(500))
}

所以,更简单化了。但是,由于需要嵌套查询,所有内容似乎都出错了。编译器抛出的当前错误是;

type mismatch;
[error]  found   : Unit
[error]  required: spray.routing.RequestContext => Unit
[error]                       if (queryType.equals("id")) {
[error]                       ^
[error] one error found
[error] (compile:compileIncremental) Compilation failed

这通常会告诉我某些东西没有返回 - 即:一个完整​​的()语句没有被击中。

使用错误指针,我唯一能想到的是switch语句可能会有一个与Success / Failure不同的结果,这可能会导致方法永远不会返回。我试图添加" case _ =>"这个段落了标准的500错误,但无济于事。

我还尝试了一种更简单的方法,即使用响应int(200或500)设置a var,并在结束时抛出complete()响应,包括此...但当然,完整()语句提前命中,线程永远不会按预期返回结果。

有人可以告诉我解决这个问题的最佳途径是什么?

1 个答案:

答案 0 :(得分:2)

您应该调试它并查看抛出此异常的位置。从我现在看到的:

if (queryType.equals("id")) {
  onComplete("a different mongo query happens here") {
    case Success(result) =>
    complete(HttpResponse(200))
    case Failure(f) =>
    complete(HttpResponse(500))
  }
}

如果没有别的,那么当这个条件没有达到时,你就有了Unit。但我很确定你需要调试它

修改

我注意到您说编译器指示错误。尝试将if添加到此处,看看是否有帮助

我设法重现了它

  if (validRequest) {
    onComplete("a mongo query happens here") {
      case Success(result) =>
        if (result.isEmpty) {
          if (queryType.equals("id")) {
            onComplete("a different mongo query happens here") {
              case Success(result) =>
                complete(HttpResponse(200))
              case Failure(f) =>
                complete(HttpResponse(500))
            }
          }
          else {
            complete(HttpResponse(500))
          }
        } else {
          complete(HttpResponse(200))
        }

      case Failure(f) =>
        complete(HttpResponse(500))
    }
  } else {
    complete(HttpResponse(500))
  }

以上代码有效