For Comprehension 中对期货的错误理解

Flawed Understanding of Futures in For Comprehension

很可能我没有正确使用 For 理解,但我认为我的问题相对通用。我在播放动作中创建了两个 Futures

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

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

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

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

 } yield wsResponse

我的问题
当我执行上面的代码时,在缓存中找不到 value,第二个 Future(网络服务调用)仍然是 created/executed - 我不想要。

我对for理解的理解是,即使第二个任务不直接依赖第一个任务,第二个任务也只会运行如果第一个任务成功完成。

如果在缓存中找不到 valuevalue = None
这就是为什么第二个 Future 仍然得到 created/executed - 因为 None 仍然被认为是第一个 Future 的成功完成?

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

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

Is this why the 2nd Future still gets created/executed - because None is still considered a successful completion of the first Future?

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

我不知道 callWebService 的签名是什么,但如果您想在 None 停止,您可以 filter Future,它将导致它失败,并且 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