给定Future [T]我可以用onComplete回调写函数返回T吗?

时间:2013-04-08 09:29:17

标签: scala

我有这个方法:

def findById(id: String): Customer = {
     (new CustomerDaoEs).retrieve(Id[Customer](id)) onComplete {
      case Success(customer) => customer
      case Failure(t) => {
        throw new InvalidIdException(id.toString, "customer")
      }
    }
  }

当然,问题是这会返回Unit而不是Customer ...所以基本上onComplete的行为并不像模式匹配。

有没有办法继续返回客户(或选项[客户])并使这项工作变得更好(我的意思是保持这个完整的干净结构)?

2 个答案:

答案 0 :(得分:5)

您可以使用exception方法更改recover

def findById(id: String): Future[Customer] = {
  (new CustomerDaoEs).retrieve(Id[Customer](id)).recover{ case _ => throw new InvalidIdException(id.toString, "customer") }
}

然后你可以像这样使用你的方法:

val customer = Await.result(findById("cust_id"), 5.seconds)

或者,您可以使用None替换异常:

def findById(id: String): Future[Option[Customer]] = {
  (new CustomerDaoEs).
    retrieve(Id[Customer](id)).
    map{ Some(_) }.
    recover{ case _ => None }
}

答案 1 :(得分:4)

主要问题是onComplete是非阻塞的。因此,您必须使用Await并返回结果。

def findById(id: String): Customer = 
  Await.result(
    awaitable = (new CustomerDaoEs).retrieve(Id[Customer](id))),
    atMost = 10.seconds
  )

但我建议保持代码不阻塞,并使findById返回Future[Customer]