首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Scala recover或recoverWith

Scala recover或recoverWith
EN

Stack Overflow用户
提问于 2016-04-13 06:01:22
回答 2查看 50.1K关注 0票数 56

我们在Scala的公司中正在开发一些系统,我们有一些疑问。我们正在讨论如何映射未来的异常,我们不知道什么时候应该使用选项1或选项2。

代码语言:javascript
复制
val created: Future[...] = ???

选项1:

代码语言:javascript
复制
val a = created recover {   
  case e: database.ADBException =>
    logger.error("Failed ...", e)
    throw new business.ABusinessException("Failed ...", e) 
}

选项2:

代码语言:javascript
复制
val a = created recoverWith {   
  case e: database.ADBException =>
    logger.error("Failed ...", e)
    Future.failed(new business.ABusinessException("Failed ...", e))
}

谁能解释一下我应该什么时候做选项1或选项2?有什么不同?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-04-13 07:10:01

答案在scaladoc中描述得很清楚:

代码语言:javascript
复制
  /** 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)。

所以,这是经验法则:

如果使用已经返回Future的内容进行恢复,请使用recoverWith,否则请使用recover

更新在您的案例中,最好使用recover,因为它会在Future中为您包装异常。否则就不会有性能上的提升,所以你只能避免一些样板文件。

票数 83
EN

Stack Overflow用户

发布于 2018-01-23 16:45:42

使用recoverWith会要求您返回一个包装的未来,而使用recover则会要求您抛出一个异常。

代码语言:javascript
复制
.recoverWith # => Future.failed(t)
.recover # => throw t

我更喜欢使用recoverWith,因为我认为函数式编程更喜欢返回对象而不是抛出异常,这不是一种函数式风格,即使它是内部代码块,我认为它仍然适用。

然而,如果我在恢复块中有一段内部代码,可能会抛出异常,那么,在这种情况下,与其捕获它并用Future包装它,或者尝试它,我还不如结合recover运行这段代码,它会为你处理异常包装,这将使代码更具可读性和紧凑性。

票数 18
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36584845

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档