我有一个函数必须返回一个FutureUnit。
在我的函数中,我编写了一个返回FutureIOResult的文件。未来和IOResult都有失败的状态。
我想在我的函数中检查未来和IOResult的成功和失败,但是从这个函数返回一个FailureUnit,这可能吗?
下面的代码是报告错误:
discarded non-Unit value
[error] Future.successful(Unit)
discarded non-Unit value
[error] Future.failed(e)这是我的功能:
def create(filePath: String, fileStream: Source[ByteString, Any]): Future[Unit] = {
val writeResultFuture: Future[IOResult] = fileStream.runWith(FileIO.toPath(filePath))
writeResultFuture map { writeResult =>
writeResult.status match {
case Success(_) =>
logger.info(s"Successfully uploaded: ${fileInfo.fileName} to: $filePath")
Future.successful(Unit)
case Failure(e) =>
logger.error(s"Failed to upload: ${fileInfo.fileName} to: $filePath", e)
Future.failed(e)
}
} recover {
case e =>
logger.error(s"Failed to upload: ${fileInfo.fileName} to: $filePath", e)
Future.failed(e)
}
}发布于 2018-08-24 14:01:07
三件事。
Unit不是Unit类型的值(它是对scala库中定义的object scala.Unit的引用)。您希望()表示Unit的值。recover的函数应该返回实际结果,而不是Future (recoverWith与期货一起工作)。map的函数也返回实际结果。如果你真的需要返回一个flatMap,你会想要Future所以,像这样的东西应该有效:
writeResultFuture.map { writeResult =>
writeResult.status match {
case Success(_) =>
logger.info(s"Successfully uploaded: ${fileInfo.fileName} to: $filePath")
case Failure(e) =>
logger.error(s"Failed to upload: ${fileInfo.fileName} to: $filePath", e)
throw e
}
}.recover { case e =>
logger.error(s"Failed to upload: ${fileInfo.fileName} to: $filePath", e)
throw e
}更好的方法是使用onFailure而不是recover -这样就不需要重新抛出了。只需执行.onFailure { e => logger.error(...) },请注意,您正在以这种方式记录错误两次(一次在map中,另一次在recover/onFailure中).考虑一起删除recover部件。
writeResultFuture.map(_.status).map {
case Success(_) => logger.info(s"Successfully uploaded: ${fileInfo.fileName} to: $filePath")
case Failure(e) => logger.error(s"Failed to upload: ${fileInfo.fileName} to: $filePath", e)
throw e
}发布于 2018-08-24 14:01:43
这样做可能会奏效:
writeResultFuture flatMap { writeResult =>
writeResult.status match {
case Success(_) =>
logger.info(s"Successfully uploaded: ${fileInfo.fileName} to: $filePath")
Future.successful()
case Failure(e) =>
Future.failed(e)
}
} recover {
case e =>
logger.error(s"Failed to upload: ${fileInfo.fileName} to: $filePath", e)
}使用flatMap将扁平match语句返回的嵌套Future,recover现在返回Unit,因此结果是Future[Unit]。recover将捕获生成的所有错误,因此不需要在内部Failure大小写中打印任何内容。
发布于 2018-08-24 14:09:55
您正在返回未来的,所以您的最终结果将是类型未来[未来…],在您的情况下,我们根本不需要嵌套,因此我们可以将代码更改为:
免责声明:我只在这里输入了代码,它还没有被输入,YMMV。没有保证。等
fileStream.runWith(FileIO.toPath(filePath)) transform {
case Failure(e) => Failure(e)
case Success(i: IOResult) => i.status
} andThen {
case Success(_) =>
logger.info(s"Successfully uploaded: ${fileInfo.fileName} to: $filePath")
case Failure(e) =>
logger.error(s"Failed to upload: ${fileInfo.fileName} to: $filePath", e)
}
} map { _ => () }https://stackoverflow.com/questions/52005127
复制相似问题