当它们是def中的最后一条语句时,onSuccess和onFailure不会返回任何内容

Exp*_*rer 0 scala scalaz scala-collections

我正在尝试与期货的收集工作,并且无法根据未来状态从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
}
}
Run Code Online (Sandbox Code Playgroud)

现在,按照Scala约定,我函数的最后一条语句成为我函数的return语句。在这个函数中,基本上应该是ie 的输出if (stageProcessingExceptions.isEmpty) Success及其对应else的结果或onFailureie 的结果new Exception(ex.getMessage))。但是,编译器不断告诉我,返回类型是单位而不是预期的析取。有人可以在这里帮我吗?谢谢

Cha*_*kar 5

当您说函数的最后一条语句成为return语句时,您是绝对正确的。但是,如果你看到的方法定义onSuccessonFailure,他们都返回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 _ =>
  }
Run Code Online (Sandbox Code Playgroud)

在类似的行上,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 _ =>
  }
Run Code Online (Sandbox Code Playgroud)

在您的情况下,您可以做的是在将来而不是onComplete上应用map函数。这将帮助您传播所需的类型。另外,如果您想处理将来失败的情况,则可以为将来添加恢复块,如下所示:

 .recover {
          case _ =>
         //whatever type you want to propogate ex: Left()
        }
Run Code Online (Sandbox Code Playgroud)