【问题标题】:Flawed Understanding of Futures in For ComprehensionFor Comprehension 中对期货的错误理解
【发布时间】:2016-03-03 00:49:14
【问题描述】:

很可能我没有正确使用For 理解,但我认为我的问题相对一般。我在 Play Action 中创建了两个 Futures

  1. 第一个调用我的缓存来获取值
  2. 然后第二个调用 Web 服务(但不依赖缓存中的值)

尽管我可以在for 之外实例化这些Futures 以使它们有机会并行运行,但我希望它们按顺序排列,因为我只想要第二个Future(网络服务调用)如果在缓存中找到value,则创建。

for {
        value <- getValueFromCache   // Future[Option[String]]

        wsResponse <- callWebService(value)   // Future[WSResponse]

 } yield wsResponse

我的问题
当我执行上述操作时,在缓存中找不到 value,仍然会创建/执行第二个 Future(Web 服务调用) - 我不想要。

我对@9​​87654329@理解的理解是,即使第二个任务不直接依赖于第一个,第二个也只有在第一个成功完成的情况下才会运行。

如果在缓存中找不到value,则value = None
这就是为什么第二个Future 仍然被创建/执行的原因 - 因为None 仍然被认为是第一个Future 的成功完成?

在什么情况下不会创建第二个Future - 当且仅当第一个FutureException 结尾?

我正在考虑使用if 1st not complete properly then do not continue 类型的语句,但这仍然让我对for 如何工作的理解存在很大差距。

【问题讨论】:

    标签: scala playframework playframework-2.0


    【解决方案1】:

    这就是为什么第二个 Future 仍然被创建/执行的原因 - 因为 None 仍然被认为是第一个 Future 的成功完成?

    是的,您最终得到一个成功完成但包含完全有效的NoneFuture

    我不知道callWebService的签名是什么,但是如果你想停在None,你可以filterFuture,这会导致它失败,后面的行在for-comprehension 不会执行。或者您也可以尝试匹配来自Option 的值,这也会导致FutureNone 上失败。

    for {
        value <- getValueFromCache.filter(_.nonEmpty)
        wsResponse <- callWebService(value) // requires `callWebService` to accept an Option
    } yield wsResponse
    

    或者

    for {
        Some(value) <- getValueFromCache
        wsResponse <- callWebService(value) // requires `callWebService` to accept the type contained in the `Option`
    } yield wsResponse
    

    甚至

    for {
        value <- getValueFromCache.map(_.get)
        wsResponse <- callWebService(value)
    } yield wsResponse
    

    【讨论】:

    • m-z,你真是个天才——请原谅我的法语。谢谢。
    猜你喜欢
    • 2015-01-21
    • 2016-12-25
    • 1970-01-01
    • 1970-01-01
    • 2017-03-26
    • 1970-01-01
    • 2015-06-08
    • 2016-12-31
    • 1970-01-01
    相关资源
    最近更新 更多