Scala 中未来的 onComplete 和 foreach 有什么区别?

What is the difference between onComplete and foreach for a future in Scala?

我想知道在 Scala 中使用 Future 时 onComplete 和 foreach 之间的区别。

f onComplete (_ => doSomething(_))

f foreach (_ => doSomething(_))

  1. 以上几行代码是否导致相同的结果?

  2. 如果我只想在 Future f 完成后对其进行操作。我应该怎么办?我应该像这样使用 isCompleted 吗:

    if(f.isCompleted) f onComplete (_ => doSomething(_))

非常感谢你们

主要区别在于即使 future 以 失败 完成,也会调用 onComplete 回调,而 foreach(和 onSuccess ) 函数仅在 成功 结果的情况下被调用。

事实上,onComplete的参数是一个函数Try[T] => U:如果future成功,你传递的函数将以Success[T]作为参数调用,或者以Failure 如果出现异常:

val f = Future { ??? } // this future completes with a failure

// foreach only calls the callback if the future is successful
f.foreach(_ => thisWillNeverExecute()) 

// This will print "future failed" after the future completes
f.onComplete {
  case Success(_) => println("future completed successfully")
  case Failure(e) => println("future failed")
}

另外,你不需要检查任何东西来调用提到的方法:onComplete/onSuccess/onFailure/foreach all schedule a callback that is只有在未来完成时,才会调用你在范围内的隐式 ExecutionContext

即使 isCompleted 为 false 也可以调用它们,它们只会在 future 成功完成或失败时执行,具体取决于您选择的是哪一个。

来看看他们的签名:

def onComplete[U](@f: Try[T] => U)(implicit executor: ExecutionContext): Unit
  • onComplete 接受一个 Try[T] => U 函数:这个函数将在未来完成时在 implicit executor 上执行。如果未来成功,则参数将是 Success[T],如果未来失败,则参数将是 Failure

def onFailure[U](pf: PartialFunction[Throwable, U])(implicit executor: ExecutionContext): Unit
  • onFailure 参数是一个 PartialFunction,它仅在 implicit executor 上执行,如果 future 失败且 Throwable 定义了 pf。它与仅匹配一些 Failure 调用 onComplete 基本相同,事实上这正是它在标准库中的实现方式。

def onSuccess[U](pf: PartialFunction[T, U])(implicit executor: ExecutionContext): Unit
  • onSuccess 参数是与 onFailure 对称的 PartialFunction,如果 future 成功完成且提供的 PartialFunction 仅在 implicit executor 上执行] 是为值定义的。

def foreach[U](f: T => U)(implicit executor: ExecutionContext): Unit
  • foreachonSuccess基本一样,只是需要一个total函数。这意味着如果 Future 成功完成,f 总是被执行

N.B.: 'onSuccess' 和 'onFailure' 将在 2.12 中弃用。我建议您阅读 this series of posts by Viktor Klang 以了解您将如何受到这些变化的影响