清除 Promise 中的 onComplete 函数列表

Clear onComplete functions list in Promise

这个片段

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]) 的承诺。有没有办法清除或重写此列表?

这在技术上是可行的。但绝对不是你想要的方式。如果我们在一个 ExecutionContext 中执行 Future(或 Promise),而在另一个中执行回调,我们可以终止回调的 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 之前完成,这意味着 两个 回调都会被调用,而不仅仅是第二个。但是如果它还没有 运行,那么只会触发一个回调。没有确定的好方法,这会导致一些真正可怕的错误。