如果我有以下理解,期货将按顺序执行:f1
,f2
,f3
:
val f = for {
r1 <- f1
r2 <- f2(r1)
r3 <- f3(r2)
} yield r3
然而,对于这一个,所有的期货都是同时开始的:
val f = for {
r1 <- f1
r2 <- f2
r3 <- f3
} yield ...
如何执行订单?(我希望此执行顺序f1
,f2
,f3
)
答案 0 :(得分:3)
f1
,f2
,f3
是多么重要:未来将在创建后立即开始执行。在第一种情况下,f2(r1)
必须是函数返回未来,因此将在调用函数时开始执行,这在r1
可用时发生。
如果第二种情况相同(f2
是一个函数),那么行为将与第一种情况相同,您的期货将按顺序执行,一个接一个地执行。
但是如果您在for
之外创建期货,只需将它们分配给变量f1
,f2
,f3
,那么当您进入理解时,他们已经正在运行。
答案 1 :(得分:2)
Future
是热切的构造,也就是说,一旦创建,你就无法决定它们何时被处理。如果当你试图在for-comprehension中使用它时Future
已经存在,那么你已经失去了对它的执行顺序进行排序的能力。
如果要对接受Future
参数的方法强制执行排序,那么您需要将评估包装在thunk中:
def foo(ft: => Future[Thing], f2: => Future[Thing]): Future[Other] = for{
r1 <- ft
r2 <- f2
} yield something(r1, r2)
另一方面,如果您想在方法正文中定义Future
,则代替val
使用def
def foo() ={
def f1 = Future{ code here... }
def f2 = Future{ code here... }
for{
r1 <- f1
r2 <- f2
} yield something(r1, r2)
答案 2 :(得分:2)
执行期货以进行理解是默认行为。当很少有任务被并行处理而没有任何阻塞时,这是很好的。
但是如果你想保留处理顺序,你必须采取行动:
使用andThen
运算符
val allposts = mutable.Set[String]()
Future {
session.getRecentPosts
} andThen {
posts => allposts ++= posts
} andThen {
posts =>
clearAll()
for (post <- allposts) render(post)
}