For Comprehension 中对期货的错误理解
Flawed Understanding of Futures in For Comprehension
很可能我没有正确使用 For
理解,但我认为我的问题相对通用。我在播放动作中创建了两个 Futures
。
- 第一次调用我的缓存获取一个值
- 然后第二个调用 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
理解的理解是,即使第二个任务不直接依赖第一个任务,第二个任务也只会运行如果第一个任务成功完成。
如果在缓存中找不到 value
,value = None
。
这就是为什么第二个 Future
仍然得到 created/executed - 因为 None
仍然被认为是第一个 Future
的成功完成?
在什么情况下不会创建第二个 Future
- 当且仅当第一个 Future
以 Exception
完成时?
我正在考虑使用 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?
是的,您最终得到一个成功完成但包含 None
的 Future
,这是完全有效的。
我不知道 callWebService
的签名是什么,但如果您想在 None
停止,您可以 filter
Future
,它将导致它失败,并且 for-comprehension 中的后续行将不会执行。或者您也可以尝试匹配 Option
中的值,这也会导致 Future
在 None
.
上失败
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
很可能我没有正确使用 For
理解,但我认为我的问题相对通用。我在播放动作中创建了两个 Futures
。
- 第一次调用我的缓存获取一个值
- 然后第二个调用 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
理解的理解是,即使第二个任务不直接依赖第一个任务,第二个任务也只会运行如果第一个任务成功完成。
如果在缓存中找不到 value
,value = None
。
这就是为什么第二个 Future
仍然得到 created/executed - 因为 None
仍然被认为是第一个 Future
的成功完成?
在什么情况下不会创建第二个 Future
- 当且仅当第一个 Future
以 Exception
完成时?
我正在考虑使用 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?
是的,您最终得到一个成功完成但包含 None
的 Future
,这是完全有效的。
我不知道 callWebService
的签名是什么,但如果您想在 None
停止,您可以 filter
Future
,它将导致它失败,并且 for-comprehension 中的后续行将不会执行。或者您也可以尝试匹配 Option
中的值,这也会导致 Future
在 None
.
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