【问题标题】:Proper way to check the value of completed Promise?检查已完成 Promise 值的正确方法?
【发布时间】:2015-03-16 00:41:03
【问题描述】:

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

有一个方法可以检查 Scala(从 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 concurrency promise


    【解决方案1】:

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

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

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

    所以你可以在这里做的是使用模式匹配。 Some/None 模式匹配检查已完成/未完成,因此您无需显式检查 .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 在他的回答中所展示的内容,尽管我想说您很有可能实际上应该处理 错误不完整 个案例,而不仅仅是将它们视为false

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

    【讨论】:

      【解决方案2】:

      Future[T].value 返回一个 Option[Try[T]],如果未来尚未完成,则为 none,因此您无需同时检查 isCompleted。这意味着您可以将方法编写为:

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

      【讨论】:

        【解决方案3】:

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

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

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

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

        【讨论】:

        • 给任何可能关注的人 - 如果您想投反对票,请发表评论。它可以帮助我了解答案中的错误。
        猜你喜欢
        • 2011-03-11
        • 2012-07-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-08-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多