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

查看:16
本文介绍了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] = {

recover 将简单的结果包装在 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).

所以,这是经验法则:

如果你用已经返回Future的东西恢复,使用recoverWith,否则使用recover.

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

更新在您的情况下,首选使用 recover,因为它会为您在 Future 中包装异常.否则就没有性能提升或任何东西,所以你只需避免一些样板.

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天全站免登陆