【问题标题】:Given a Future[T] can I write function with onComplete callback which returns T?给定一个 Future[T],我可以编写带有返回 T 的 onComplete 回调的函数吗?
【发布时间】:2013-04-08 09:29:17
【问题描述】:

我有这个方法:

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 的行为并不像模式匹配。

有什么方法可以让客户(或 Option[Customer])不断返回并使这项工作顺利进行(我的意思是保持这个 onComplete 干净的结构)?

【问题讨论】:

    标签: scala


    【解决方案1】:

    您可以使用recover 方法更改exception

    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 }
    }
    

    【讨论】:

      【解决方案2】:

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

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

      但是我更愿意建议保持代码非阻塞并让 findById 返回Future[Customer]

      【讨论】:

      • 但是如果id 是错误的怎么办。如果您想要留言,请返回Future[Either[String,Customer]]Future[Option[Customer]]
      • 我不认为每个异常都应该像给定的答案那样映射到 InvalidIdException 。如果连接由于某种原因被关闭怎么办?那肯定不是无效的 id。
      • @ziggystar:期货已经封装了错误(如果有的话),因此使用任何一个通常都是多余的。对于您确实需要明确表示异常的情况,现在使用Try 更为惯用。在这里查看我的其他答案以获得一些相关的帮助:stackoverflow.com/a/15776974/1632462。但无论如何,这在将来映射/平面映射时很有用,API 不应返回 Future[Either[String,Customer]](也不应返回 Future[Try[Customer]])。正如我所说,这是多余的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-12-08
      • 1970-01-01
      • 2015-05-20
      • 2011-01-30
      • 2019-01-06
      • 2022-01-18
      • 1970-01-01
      相关资源
      最近更新 更多