非阻塞尾递归

时间:2015-08-03 17:15:31

标签: scala recursion future

我有一个尾递归实现,如下所示

@tailrec
def generate() : String = {
  val token = UUID.randomUUID().toString
  val isTokenExist = Await.result(get(token), 5.seconds).isDefined
  if(isTokenExist) generate()
  else token
}

get(token)将返回Future[Option[Token]]

我知道在未来阻挡并不好。我尝试返回Future[String]而不是String。但似乎除非我等待isTokenExist完成,否则它是不可能的。

实施此任何其他方式/建议?

3 个答案:

答案 0 :(得分:0)

get(token)发生了什么,如果它第一次超过5秒,第二次也不会超过它?

如果你真的需要检查(并且碰撞非常不太可能),你可能只需要阻止。否则,如果5s不够,该方法将永远不会返回,并且您将在很长一段时间后获得Stackoverflow。

我可能会保持简单:

def generate() : String = {
  val token = UUID.randomUUID().toString
  if(get(token).isDefined) generate()
  else token
}

如果您需要优化此代码中的某些内容,则可能是get(token)方法。

答案 1 :(得分:0)

如果将来包装get(token),则可以使用将来的onComplete函数。类似的东西:

val f: Future[Token] = Future {
  get(token)
}
f onComplete {
     case Success(token) => generate()
     case Failure(t) => println("An error has occured: " + t.getMessage)
}

有关详细信息,请查看:http://docs.scala-lang.org/overviews/core/futures.html

答案 2 :(得分:0)

在这种情况下,

generate不必是尾递归的,因为它使用了Futures(请阅读:How do I make a function involving futures tail recursive?进行解释)。

这对你有用吗?

  def generate: Future[String] = {
    val token = UUID.randomUUID().toString
    get(token).flatMap {
      case None => generate
      case _    => Future.successful(token)
    }
  }