为什么Scala';s Future.onComplete需要一个ExecutionContext

为什么Scala';s Future.onComplete需要一个ExecutionContext,scala,concurrency,Scala,Concurrency,无法承诺。完成只需运行Future.onComplete的回调,而不是完全通过执行上下文,并且据我所知,计划未来。onComplete的回调供以后使用,并可能在另一个线程中运行它?这是实现scala Futures的设计决策,所有操作(map、flatMap等)都需要隐式ExecutionContext 如果您希望线程的可重用性更好,线程之间的上下文切换更少,我建议您看看scalaz Task,它对延迟计算的抽象略有不同:您可以向onComplete提供自己的执行上下文,这将在同一线程上运行代码

无法
承诺。完成
只需运行
Future.onComplete
的回调,而不是完全通过
执行上下文
,并且据我所知,计划
未来。onComplete
的回调供以后使用,并可能在另一个线程中运行它?

这是实现scala Futures的设计决策,所有操作(map、flatMap等)都需要隐式ExecutionContext


如果您希望线程的可重用性更好,线程之间的上下文切换更少,我建议您看看scalaz Task,它对延迟计算的抽象略有不同:

您可以向
onComplete
提供自己的
执行上下文,这将在同一线程上运行代码:

val immediateContext: ExecutionContext = new ExecutionContext {
  def execute(runnable: Runnable) {
    runnable.run()
  }
  def reportFailure(cause: Throwable) {}
}
您甚至可以将其设置为
隐式
,对于希望在另一个线程中执行的情况,您可以提供
scala.concurrent.ExecutionContext.global
或其他上下文

下面是一个测试,它是如何工作的:

val immediateContext: ExecutionContext = new ExecutionContext {
  override def reportFailure(cause: Throwable): Unit = {}
  override def execute(runnable: Runnable): Unit = {
    println("Executing")
    runnable.run()
    println("Executed")
  }
}

def testContext(): Unit = {
  println("Scheduling on an uncompleted future")
  val p = Promise[Int]()
  println("Scheduling")
  p.future.onComplete { _ => println("Completed") }(immediateContext)
  println("Scheduled")
  p.complete(Success(5))

  println()

  println("Scheduling on an already completed future")
  val p2 = Promise[Int]().complete(Success(5))
  println("Scheduling")
  p2.future.map { n =>
    println("Mapping")
    n * 2
  }(immediateContext).onComplete{
    case Success(n) => println(s"Completed: $n") 
    case _ =>
  }(immediateContext)
  println("Scheduled")

  println()

  println("Using scala.concurrent.ExecutionContext.global for comparison")
  val p3 = Promise[Int]().complete(Success(5))
  println("Scheduling")
  p3.future.onComplete {
    _ => println("Completed")
  }(concurrent.ExecutionContext.global)
  println("Scheduled")
}
运行
testContext()
将打印

Scheduling on an uncompleted future
Scheduling
Scheduled
Executing
Completed
Executed

Scheduling on an already completed future
Scheduling
Executing
Mapping
Executed
Executing
Completed: 10
Executed
Scheduled

Using scala.concurrent.ExecutionContext.global for comparison
Scheduling
Scheduled
Completed