Scala恢复或recoverWith [英] Scala recover or recoverWith

查看:551
本文介绍了Scala恢复或recoverWith的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正在Scala的公司中开发一些系统,我们对此表示怀疑。我们正在讨论如何映射将来的异常,我们不知道何时应该使用选项1或选项2。

We are developing some systems in our company in Scala and we have some doubts. We were discussing about how to map the future exceptions and we don't know when we should use the option 1 or the option 2.

val created: Future[...] = ???

选项1:

val a = created recover {   
  case e: database.ADBException =>
    logger.error("Failed ...", e)
    throw new business.ABusinessException("Failed ...", e) 
}

选项2:

val a = created recoverWith {   
  case e: database.ADBException =>
    logger.error("Failed ...", e)
    Future.failed(new business.ABusinessException("Failed ...", e))
}

有人可以解释我何时应该执行选项1或选项2?差异是什么?

Could someone explain when should i do the option 1 or the option 2? What is the diff?

推荐答案

好吧,答案在scaladocs中有明确描述:

Well, the answer is clearly described in scaladocs:

  /** Creates a new future that will handle any matching throwable that this
   *  future might contain. If there is no match, or if this future contains
   *  a valid result then the new future will contain the same.
   *
   *  Example:
   *
   *  {{{
   *  Future (6 / 0) recover { case e: ArithmeticException => 0 } // result: 0
   *  Future (6 / 0) recover { case e: NotFoundException   => 0 } // result: exception
   *  Future (6 / 2) recover { case e: ArithmeticException => 0 } // result: 3
   *  }}}
   */
  def recover[U >: T](pf: PartialFunction[Throwable, U])(implicit executor: ExecutionContext): Future[U] = {

  /** Creates a new future that will handle any matching throwable that this
   *  future might contain by assigning it a value of another future.
   *
   *  If there is no match, or if this future contains
   *  a valid result then the new future will contain the same result.
   *
   *  Example:
   *
   *  {{{
   *  val f = Future { Int.MaxValue }
   *  Future (6 / 0) recoverWith { case e: ArithmeticException => f } // result: Int.MaxValue
   *  }}}
   */
  def recoverWith[U >: T](pf: PartialFunction[Throwable, Future[U]])(implicit executor: ExecutionContext): Future[U] = {

恢复将普通结果包装在 Future 中( map 的类似物),而 recoverWith 预期结果为 Future (类似于 flatMap 的结果)。

recover wraps plain result in Future for you (analogue of map), while recoverWith expects Future as the result (analogue of flatMap).

所以,这是一条经验法则:

So, here is rule of thumb:

如果您恢复了已经返回 Future ,使用 recoverWith ,否则使用 recover

If you recover with something that already returns Future, use recoverWith, otherwise use recover.

更新
在您的情况下,首选使用恢复,因为它将异常包装在未来为您服务。否则,不会有任何性能提升或任何改善,因此您只需避免使用一些样板。

update In your case, using recover is preferred, as it wraps the exception in Future for you. Otherwise there is no performance gain or anything, so you just avoid some boilerplate.

这篇关于Scala恢复或recoverWith的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆