如何在Scala中包装PartialFunction?

3
在Scala中,Future有一种救援函数(rescue function),接受一个PartialFunction作为参数。如果Future成功解析出响应,则跳过此代码;但如果失败,则调用该函数。
我想简单地将这个PartialFunction包装在一个代理(proxy)中,该代理始终执行写入统计计数器的代码。起初,我认为只需创建另一个PartialFunction即可,但很快意识到这不适用于isDefined和apply,因为我希望它每次都被调用。
我如何代理这个PartialFunction,以便在Future出现异常时始终调用我的代码?

你想让你的函数在所有失败情况下执行,还是无论如何都要执行? - Michael Zajac
仅返回所有失败。 - Dean Hiller
为什么不使用onFailure回调函数呢? - Michael Zajac
@m-z 哦,嗯,我应该想到那个的。 - Dean Hiller
1
andThen 也是一个不错的选择,因为它是一个组合器,而 onComplete 只返回一个 Unit。你可以构建一个 Future 工厂,总是为其添加一个 andThen 来记录失败日志。 - cmbaxter
1个回答

5
简而言之,您可以使用onFailure回调在Future失败时执行一些副作用代码(日志记录)。
val future = Future(1 / 0)

future.onFailure {
    case _ => println("I have seen the Future, and it doesn't look good.")
}

正如 @cmbaxter 所指出的那样,您还可以在 Future 上使用 andThen,它接受一个 PartialFunction[Try[A], B] 并返回原始的 Future。因此,您可以使用 andThen 应用具有副作用的函数,然后再使用 recover。甚至可以多次链接它们。

Future(1 / 0)
    .andThen { case Failure(_) => println("Future failed.") }
    .recover { case e: ArithmeticException => 0 }
    .andThen { case Failure(_) => println("Tried to recover, and still failed.") }

或者一个总是包含它的助手:
object FutureLogger {
     def apply[A](a: => A): Future[A] = Future(a).andThen {
         case Failure(_) => println("FAILURE")
     }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接