将scala.util.Try转换为scala.concurrent.Future
我开始将Scala 2.11代码库迁移到Scala 2.12。在我的应用程序中,我有一个如下的方法:将scala.util.Try转换为scala.concurrent.Future,scala,future,Scala,Future,我开始将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编译此文
Future {
someMethodReturningTry()
} onSuccess {
case Success(result) => processResult()
case Failure(reason) => log.error(s"Couldn't do it: ${reason.getMessage}")
}
现在,如果使用Scala 2.12编译此文件,您将获得:
自2.12.0以来,trait Future中的onSuccess方法已被弃用:改用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 {
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 Failurereason=>子句保留为空,但保留如图所示的错误记录可能更有帮助。您可以通过以下方式调整模式匹配:
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 Failurereason=>子句保留为空,但保留如图所示的错误日志记录可能更有帮助。我不清楚您为什么不
Future {
someMethodReturningTry() match {
case Success(result) => processResult(result)
case Failure(reason) => log.error(s"Couldn't do it: ${reason.getMessage}")
}
}
你可以单独处理或忽略未来的失败。我不清楚你为什么不
Future {
someMethodReturningTry() match {
case Success(result) => processResult(result)
case Failure(reason) => log.error(s"Couldn't do it: ${reason.getMessage}")
}
}
您可以单独处理或忽略未来的故障。谢谢您的建议!关于成功的好消息;someMethodReturningTry在返回失败时做了一些日志记录,但该方法可以自由地忽略该失败。我在想,我能不能摆脱成功的结构?它也感觉有点多余…@mthmulders onComplete{{uu0.flatte match{case Successresult=>…case Failurereason=>…}。谢谢你的建议!关于成功的好消息;someMethodReturningTry在返回失败时做了一些日志记录,但该方法可以自由地忽略该失败。我在想,我能不能摆脱成功的结构?它也感觉有点多余…@mthmulders onComplete{{uu0.flatte match{case Successresult=>…case Failurereason=>…}。是的,这很有意义!它不会产生不必要的深层结构,而且读起来很清楚——这正是我想要的!嗯,是的,这是有道理的!它不会产生不必要的深层结构,而且读起来很清楚——这正是我想要的!Future.fromTry?Future.fromTry对我来说不是一个好选项,因为它不能异步工作。它首先调用产生Try的方法,然后才创建承诺。Try无论如何都不是异步的Future.fromTry?Future.fromTry对我来说不是一个好选项,因为它不异步工作。它首先调用产生Try的方法,然后才创建承诺