Scala 序列中的多个期货

Multiple Futures in a Sequence in Scala

我有两个计算发生在 Future 中,如下所示:

val comp1 = Future { ... }
val comp2 = Future { ... }

我希望 运行 这样 comp2 总是在 comp1 完成后 运行s!我知道使用 for 表达式,我可以组合这两个 Future 的 like。

for {
  comp1Result <- comp1
  comp2Result <- comp2
} yield { ... }

什么可以保证 comp1 在 comp2 之前完成?我的意思是这些是在不同线程中发生的计算,并且不能保证这可能是 运行 的顺序。有没有办法保证顺序不阻塞?

Scala for comprehensions 是 'container type' 上 flatMap 和 map 调用组合的语法糖(在本例中为 Futures),因此您上面的代码等同于:

comp1.flatMap{ comp1Result => comp2 }

此处花括号内的计算仅在comp1完成且returns结果成功后发生(在失败的情况下,内部计算不会执行)。

如果你在 for comprehension 之外定义 comp2,如问题所示,那么你就是在开始计算(你只是忽略结果,直到你在 for comprehension 内),但如果你只在里面定义它for comprehension,那么它不会被启动,除非并且直到 comp1 成功完成。因此,尝试按如下方式重新调整代码:

val comp1 = Future { ... } // or you could put this construction inside the for as well
for {
  comp1Result <- comp1
  comp2Result <- Future { ... } // Only start the computation here
  comp3Result <- Future { ... } // etc. for as many such computations as you need
} yield { ... }

其他替代方法是将 comp2 声明为惰性 val(因此它实际上不会被评估 - 开始计算 - 直到它被引用),或者作为 lambda(例如 val comp2 = () => Future { ... })并调用它用线

  comp2Result <- comp2()

在理解里面。