在没有未来的情况下获得Scala承诺的结果
有没有办法直接从成功的承诺中获得价值? 为此,真的有必要将未来与承诺联系起来吗在没有未来的情况下获得Scala承诺的结果,scala,Scala,有没有办法直接从成功的承诺中获得价值? 为此,真的有必要将未来与承诺联系起来吗 scala> import scala.concurrent._ import scala.concurrent._ scala> val result = Promise[Int] result: scala.concurrent.Promise[Int] = scala.concurrent.impl.Promise$DefaultPromise@2b5fa85f scala> result
scala> import scala.concurrent._
import scala.concurrent._
scala> val result = Promise[Int]
result: scala.concurrent.Promise[Int] = scala.concurrent.impl.Promise$DefaultPromise@2b5fa85f
scala> result success 3
res0: result.type = scala.concurrent.impl.Promise$DefaultPromise@2b5fa85f
scala> result
res1: scala.concurrent.Promise[Int] = scala.concurrent.impl.Promise$DefaultPromise@2b5fa85f
scala> result.isCompleted
res4: Boolean = true
scala> result.value
<console>:12: error: value value is not a member of scala.concurrent.Promise[Int]
result.value
^
scala> result.future.value.get.get
res6: Int = 3
scala>导入scala.concurrent_
导入scala.concurrent_
scala>val结果=承诺[Int]
结果:scala.concurrent.Promise[Int]=scala.concurrent.impl.Promise$DefaultPromise@2b5fa85f
scala>结果成功3
res0:result.type=scala.concurrent.impl.Promise$DefaultPromise@2b5fa85f
scala>结果
res1:scala.concurrent.Promise[Int]=scala.concurrent.impl.Promise$DefaultPromise@2b5fa85f
scala>result.isCompleted
res4:Boolean=true
scala>result.value
:12:错误:value不是scala.concurrent.Promise[Int]的成员
结果值
^
scala>result.future.value.get.get
res6:Int=3
我正在考虑使用线程安全的“赋值一次”语义。promise对象在scala.concurrent源代码中看起来足够精简,据我所知,它是线程安全的。然而,我宁愿避免添加另一个对象(未来)。我找不到承诺成功价值的获得者。tl;博士
所以不要担心额外的分配
讨论
承诺
和未来
是互补的。前者表示计算的写入(一次)端,而后者表示读取端
因此,为了从承诺
中读取值,您将始终需要通过未来
来读取
另一方面,值得注意的是,尽管有抽象的设计,实现还是相当有效的,Promise
和Future
不是独立的实体。以下是Promise
private[concurrent] trait Promise[T] extends scala.concurrent.Promise[T] with scala.concurrent.Future[T] {
def future: this.type = this
}
因此,您可以看到p.future
实际上与p
相同,只是得到了不同的语义
总之,您可以从promise访问future
,并且不必为实例分配支付任何额外费用
此外,如果您愿意,还可以使语法更简洁
scala> implicit class DirectAccessPromise[A](val p: Promise[A]) extends AnyVal {
| def get = p.future.value.get.get
| }
defined class DirectAccessPromise
scala> val p = Promise.successful(42)
res0: scala.concurrent.Promise[Int] = scala.concurrent.impl.Promise$KeptPromise@5e8c92f4
scala> p.get
res1: Int = 42
请注意,由于包装器是一个值类,因此您将不需要支付任何额外的实例化价格,因为包装器本身将作为未来返回,因此您不会进行额外的分配。即使是这样,线程安全的成本也可能更高。不,是出于承诺的设计。可能更整洁:
wait.result(p.future,Duration.Zero)
@BenReich我相信这并不是更整洁,只是实践中的不同假设。wait.result等待承诺,而.value假定它已成功。不同的用例。您可以使用DirectAccessPromise
extendAnyVal
来节省隐式类分配成本:tl中有一个输入错误;灾难恢复:p.future==p
scala> implicit class DirectAccessPromise[A](val p: Promise[A]) extends AnyVal {
| def get = p.future.value.get.get
| }
defined class DirectAccessPromise
scala> val p = Promise.successful(42)
res0: scala.concurrent.Promise[Int] = scala.concurrent.impl.Promise$KeptPromise@5e8c92f4
scala> p.get
res1: Int = 42