我正在尝试收集期货,并且无法根据未来状态从def返回结果。下面是我的代码:
final case class StagesToRun(stages : Set[StageRun])
private def processNextStagesAndAccumulateResults(stagesToRun: StagesToRun): \/[Exception, Success] = {
val stageProcessingExceptions = mutable.Set[Exception]()
//processor.process(stagesToRun) => returns a Set[Future[\/[Exception, Success]]] and I am converting it to Future[Set[\/[Exception, Success]]] in below expression
val processResults = Future.sequence(processor.process(stagesToRun))
processResults.onSuccess {
case result => {
result.map { res =>
res.fold(
l => stageProcessingExceptions += l,
r => r
)
}
if (stageProcessingExceptions.isEmpty) Success.right
else new Exception("Got exception while processing one of the stage").left
}
}
processResults.onFailure {
case ex => new Exception(ex.getMessage)).left
}
}
现在按照Scala约定,我函数的最后一条语句成为我函数的return语句。在此函数中,基本上应该是if (stageProcessingExceptions.isEmpty) Success
及其对应的else
的输出或onFailure
的结果,即new Exception(ex.getMessage))
。但是,编译器不断告诉我,返回类型是单位而不是预期的析取。有人可以在这里帮我吗?谢谢
答案 0 :(得分:4)
当您说函数的最后一条语句成为return语句时,您是绝对正确的。但是,如果您看到onSuccess
和onFailure
的方法定义,它们都将返回Unit
作为返回类型。
从scala文档中,onSuccess的签名为
def onSuccess[U](pf: PartialFunction[T, U])(implicit executor: ExecutionContext): Unit = onComplete {
case Success(v) =>
pf.applyOrElse[T, Any](v, Predef.identity[T]) // Exploiting the cached function to avoid MatchError
case _ =>
}
在类似的行上,onFailure返回单位。
def onFailure[U](@deprecatedName('callback) pf: PartialFunction[Throwable, U])(implicit executor: ExecutionContext): Unit = onComplete {
case Failure(t) =>
pf.applyOrElse[Throwable, Any](t, Predef.identity[Throwable]) // Exploiting the cached function to avoid MatchError
case _ =>
}
在您的情况下,您可以做的是在将来而不是onComplete上应用map函数。这将帮助您传播所需的类型。 另外,如果您要处理将来失败的情况,则可以将恢复块添加为
.recover {
case _ =>
//whatever type you want to propogate ex: Left()
}
答案 1 :(得分:2)
onSuccess
和onFailure
都返回Unit
,并且旨在实现副作用。如果要返回修改后的Future
,请使用transform
。一个版本具有两个功能:第一个功能处理成功的结果,第二个功能处理异常。
processResults.transform(
{ result =>
// process result and return new result
// throw error on failure
result
},
{ ex =>
// Process exception and return new exception
ex
}
)
如果在任何一个函数中引发异常,您都会收到错误Future
。
transform
的另一个版本带有功能Try => Try
,该功能使您可以将错误Future
转换为成功的Future
,而上述版本是不可能的