将scala.util.Try转换为scala.concurrent.Future

将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编译此文

我开始将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编译此文件,您将获得:

自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的方法,然后才创建承诺