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

时间:2015-03-15 16:12:27

标签: scala concurrency promise

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

有一种方法可以检查Scala中的Promise(从2.11.5开始)是否已经完成,即isCompleted。但是,当你想获得已经完成的Promise的值时,看起来你必须编写一个像这样的unappetising链:

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

(为了完整性:我正在考虑写一些类似的东西:

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

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

有没有更好的方法?或者这是否表明我没有像预期的那样使用它?

3 个答案:

答案 0 :(得分:4)

我会说你没有像预期的那样使用它。

首先,Scala Promises主要是一种“引导”期货的机制,因此您传递的价值通常应该是期货而非Promise。这使得访问链段缩短了一段。

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

所以你可以在这里做的是使用模式匹配。 Some / None模式匹配检查已完成/未完成,因此您无需显式检查.isCompleted属性。在这里,我假设你有一个未来f而不是一个承诺,但如果你需要,你可以对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在他的回答中所表明的内容,尽管我说你很有可能实际上应该处理错误并且没有完成< / em>案例,而不仅仅是将它们视为false

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

答案 1 :(得分:2)

Future[T].value会返回Option[Try[T]],如果未来尚未完成,则为无,因此您无需另行isCompleted。这意味着您可以将方法编写为:

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

答案 2 :(得分:-1)

所以......基本上,承诺是一种包装物,它允许我们与潜在的未来互动。

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

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

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