【问题标题】:Getting the result of a Scala promise without a future在没有未来的情况下获得 Scala 承诺的结果
【发布时间】:2015-04-07 00:41:36
【问题描述】:

有没有办法直接从成功的承诺中获取价值? 为此,真的有必要将future 连接到承诺吗?

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

我正在考虑对线程安全的“赋值一次”语义使用承诺。 promise 对象在 scala.concurrent 源代码中看起来足够精简,据我所知,它是线程安全的。但是,我宁愿避免添加另一个对象(未来)。我找不到承诺的成功价值的吸气剂。

【问题讨论】:

  • 不,按照承诺的设计。
  • 也许更整洁:Await.result(p.future, Duration.Zero)
  • @BenReich 我相信这并不是更简洁,只是在实践中的假设不同。 Await.result 等待承诺,而 .value 假设它已经成功。不同的用例。

标签: scala


【解决方案1】:

tl;博士

p.future == p

所以不用担心额外的分配。


讨论

PromiseFuture 是免费的。前者代表计算的写入(一次)端,而后者是读取端。

因此,为了从 Promise 读取值,您将始终需要通过 Future 进行读取。

另一方面,值得注意的是,尽管进行了抽象设计,但实现非常高效,PromiseFuture 不是独立的实体。下面是Promisefuture的实现@

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

请注意,由于包装器是一个值类,因此您不会支付任何额外的实例化费用

【讨论】:

【解决方案2】:

DefaultPromise 返回 自身 作为未来,因此您不会进行额外分配。即使你是,线程安全的成本也可能要高得多。

【讨论】:

    猜你喜欢
    • 2020-03-22
    • 2017-12-29
    • 2019-10-06
    • 1970-01-01
    • 2017-01-25
    • 1970-01-01
    • 2020-07-08
    • 2023-03-16
    • 1970-01-01
    相关资源
    最近更新 更多