为什么 Scala 的 Future.onComplete 需要一个 ExecutionContext
Why does Scala's Future.onComplete needs an ExecutionContext
不能 Promise.complete
只是 运行 Future.onComplete
的回调,而不是一直通过 ExecutionContext
并且,据我所知,安排 Future.onComplete
稍后的回调,可能 运行 它在另一个线程中?
这是实现 scala Futures 的设计决策,所有操作(map、flatMap 等...)都需要隐式 ExecutionContext。
如果您想要更好的线程可重用性和线程之间更少的上下文切换,我建议您看一下 scalaz Task,延迟计算的抽象略有不同:http://timperrett.com/2014/07/20/scalaz-task-the-missing-documentation/
您可以将自己的 ExecutionContext
提供给 onComplete
,这将 运行 同一线程上的代码:
val immediateContext: ExecutionContext = new ExecutionContext {
def execute(runnable: Runnable) {
runnable.run()
}
def reportFailure(cause: Throwable) {}
}
您甚至可以将其设置为 implicit
,并且对于您希望在另一个线程中执行的情况,您可以提供 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
不能 Promise.complete
只是 运行 Future.onComplete
的回调,而不是一直通过 ExecutionContext
并且,据我所知,安排 Future.onComplete
稍后的回调,可能 运行 它在另一个线程中?
这是实现 scala Futures 的设计决策,所有操作(map、flatMap 等...)都需要隐式 ExecutionContext。
如果您想要更好的线程可重用性和线程之间更少的上下文切换,我建议您看一下 scalaz Task,延迟计算的抽象略有不同:http://timperrett.com/2014/07/20/scalaz-task-the-missing-documentation/
您可以将自己的 ExecutionContext
提供给 onComplete
,这将 运行 同一线程上的代码:
val immediateContext: ExecutionContext = new ExecutionContext {
def execute(runnable: Runnable) {
runnable.run()
}
def reportFailure(cause: Throwable) {}
}
您甚至可以将其设置为 implicit
,并且对于您希望在另一个线程中执行的情况,您可以提供 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