清除 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
之前完成,这意味着 两个 回调都会被调用,而不仅仅是第二个。但是如果它还没有 运行,那么只会触发一个回调。没有确定的好方法,这会导致一些真正可怕的错误。
这个片段
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
之前完成,这意味着 两个 回调都会被调用,而不仅仅是第二个。但是如果它还没有 运行,那么只会触发一个回调。没有确定的好方法,这会导致一些真正可怕的错误。