检查已完成 Promise 值的正确方法?

Proper way to check the value of completed Promise?

上下文:我有一个函数,我想在开始时检查某个 Promise 是否 a) 已经完成并且 b) 具有特定值。

Scala (as of 2.11.5) 中有一种检查Promise是否已经完成的方法,即isCompleted。然而,当你想获得一个已经完成的 Promise 的值时,看起来你必须像这样写一个倒胃口的链:

val p = Promise[Boolean]
val result = p.future.value.get.toOption.get

(为了完整起见:我正在考虑写这样的东西:

if (p.isCompleted && p.future.value.get.toOption.get == true)

但对该代码的丑陋感到震惊:))

有没有更好的办法?或者这是否表明我没有按照预期的方式使用它?

我会说你没有按照预期的方式使用它。

首先,Scala Promises 主要是 "bootstrapping" Futures 的一种机制,因此您传递的值通常应该是 Futures 而不是 Promises。这使得访问链缩短了一段。

接下来,您经历这么多层的原因是 Futures 封装了两种效果 - 并发和失败。 Future 可以完成也可以失败,所以检查 isCompleted 只是故事的一半。

所以你在这里可以做的是使用模式匹配。 Some/None 模式匹配检查 completed/not 已完成,因此您不需要对 .isCompleted 属性 进行显式检查。在这里我假设你有一个 Future f 而不是 Promise,但如果你需要的话你可以用 p.future 做同样的事情):

f.value match {
    case Some(Success(v)) => // completed successfully - access value v
    case Some(Failure(e)) => // completed with failure - access error e
    case None => // not yet complete
}

在你的具体情况下,这将归结为 Sarvesh 在他的回答中所展示的内容,尽管我想说你很有可能实际上应该处理 error未完成 个案例,而不是将它们视为 false

另一种使用 Futures 的方法是以事件驱动的方式使用它们。您可以根据要观察的结果在 f.andThenf.onFailuref.onSuccess 上注册事件,并且您可以使用各种其他机制来转换其结果等。

所以...基本上 promise 是一种包装器,它允许我们与潜在的未来进行交互。

所以...从已完成的承诺中获取您的未来并使用模式匹配。

在这种情况下,p.future.value 将是 Option[ Try [ Boolean ] ]

val yourBool = p.future.value match {
  case Some( Success( bool ) ) => bool
  case _ => false
}

Future[T].value returns 一个 Option[Try[T]] 即 none 如果未来还没有完成所以你不需要也检查 isCompleted。这意味着您可以将方法编写为:

def hasValue[T](p: Promise[T], value: T) = p.future.value.flatMap(_.toOption) == Some(value)