对理解中期货的错误理解

Jam*_*ieP 2 scala playframework playframework-2.0

我很可能没有For恰当地使用理解,但我认为我的问题相对普遍.我Futures在Play Action中创建了两个.

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

即使我可以Futurefor它们之外实例化它们以给它们并行运行的机会,但我希望它们按顺序排列,因为我只想在缓存中找到第二个Future(Web服务调用)value.

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

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

 } yield wsResponse
Run Code Online (Sandbox Code Playgroud)

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

我对理解的for理解是,即使第二个任务不直接依赖于第一个任务,第二个任务只有在第一个任务成功完成时才会运行.

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

在什么情况下第二个Future不会被创建 - 如果且仅当第一个Future完成时Exception

我正在考虑使用一种if 1st not complete properly then do not continue陈述,但这仍然让我理解如何for处理一个很大的差距.

Mic*_*jac 6

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

是的,你最终Future成功完成但包含None,这是完全有效的.

我不知道签名什么callWebService的,但如果你想停止None,你可以filterFuture,这将导致失败,并在换理解后续行不会执行.或者您也可以尝试匹配来自的值Option,这也会导致Future失败None.

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

要么

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

甚至

for {
    value <- getValueFromCache.map(_.get)
    wsResponse <- callWebService(value)
} yield wsResponse
Run Code Online (Sandbox Code Playgroud)