【问题标题】:Clear onComplete functions list in Promise清除 Promise 中的 onComplete 函数列表
【发布时间】:2015-05-17 19:24:35
【问题描述】:

这个sn-p

val some = Promise[Int]()
some.success(20)
val someFuture = some.future
someFuture.onSuccess {case i => println(i)}
someFuture.onComplete {case iTry => List(println(iTry.get*2), println(iTry.get*3))}

在完成时创建带有 3 个回调 (List[CallbackRunnable]) 列表的 Promise。有没有办法清除这个 List 或重写它?

【问题讨论】:

  • 不这么认为。除非回调可能在不同的 ExecutionContext 中,您可以单独杀死。
  • 不是真的,你总是可以让未来可变并重新分配它。
  • @BenjaminGruenbaum 我不认为重新分配会起作用。

标签: scala promise future


【解决方案1】:

这在技术上是可行的。但绝对不是你想要的方式。如果我们在一个ExecutionContext 中执行Future(或Promise),在另一个ExecutionContext 中执行回调,我们可以终止回调的ExecutionContext,使其无法完成。这在 REPL 中有效(在某处引发异常),但在实际代码中实际尝试是一个糟糕的主意:

import scala.concurrent._
import java.util.concurrent.Executors    

val ex1 = Executors.newFixedThreadPool(1)
val ex2 = Executors.newFixedThreadPool(1)
val ec1 = ExecutionContext.fromExecutorService(ex1)
val ec2 = ExecutionContext.fromExecutorService(ex2)

val f = Future { Thread.sleep(30000); println("done") }(ec1) // start in one ExecutionContext

f.onComplete { case t => println("onComplete done") }(ec2) // start callback in another ExecutionContext

ec2.shutdownNow

f.onComplete { case t => println("onComplete change") }(ec1) // start another callback in the original ExecutionContext

第一个onComplete 不会运行(在后台抛出异常,这可能会或可能不会导致其他地方发生可怕的事情),但第二个会运行。但这真的很糟糕,所以不要这样做。

即使有清除回调的构造,使用它也不是一个好主意。

someFuture.onComplete { case result => // do something important }

someFuture.clearCallbacks() // imaginary method to clear the callbacks

someFuture.onComplete { case result =>> // do something else }

这个假设代码的执行是不确定的。 someFuture 可以在调用 clearCallbacks 之前完成,这意味着 both 回调将被调用,而不仅仅是第二个。但如果它还没有运行,那么只会触发一个回调。没有一个很好的方法来确定它,这会导致一些真正可怕的错误。

【讨论】:

    猜你喜欢
    • 2019-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多