我开始将Scala 2.11代码库迁移到Scala 2.12。在我的应用程序中,我有一个看起来像这样的方法:
Future {
someMethodReturningTry()
} onSuccess {
case Success(result) => processResult()
case Failure(reason) => log.error(s"Couldn't do it: ${reason.getMessage}")
}
现在,如果你用Scala 2.12编译它,你会得到:
方法onSuccess in trait Future已被弃用(自2.12.0起):改为使用
foreach
或onComplete
(请记住它们采用的是总计而非部分函数)
所以我开始探索如何以优雅的方式解决这个问题。
someMethodReturningTry()
方法确实应返回Try[]
,因为它涉及解析某些文本结构并且可能会失败,所以我更喜欢保留该方法的返回类型同样的。
我能想到的最好的是
Future {
someMethodReturningTry()
} flatMap {
case Success(result) => Future.successful(result)
case Failure(reason) => Future.failed(reason)
} onComplete {
case Success(result) => processResult()
case Failure(reason) => log.error(s"Couldn't do it: ${reason.getMessage}")
}
但这感觉有点多余:创建一个Future
只是为了模拟未来某些事物(已经在Future
内捕获)的事实进展顺利。
这种方法创造了一个额外的Future
我希望摆脱,但我无法弄清楚如何。有什么建议吗?
答案 0 :(得分:3)
我不清楚为什么你不只是......
Future {
someMethodReturningTry() match {
case Success(result) => processResult(result)
case Failure(reason) => log.error(s"Couldn't do it: ${reason.getMessage}")
}
}
您可以单独处理或忽略Future
失败。
答案 1 :(得分:2)
您可以通过以下方式调整模式匹配:
Future {
someMethodReturningTry()
} onComplete {
case Success(Success(result)) => processResult()
case Success(Failure(reason)) => log.error(s"Couldn't do it: ${reason.getMessage}")
case Failure(reason) =>
log.error(s"The future failed: ${reason.getMessage}")
// or do nothing
}
请注意,仅当onSuccess
成功时才会执行Future
回调,因此如果Future
包含异常,则原始代码不会执行任何操作。如果这是您的意图,您可以将case Failure(reason) =>
子句置于空白处(但是如图所示保留错误记录可能更有帮助。)