scala - 在 Scala 中混契约(Contract)步、异步和并行计算以理解 future 的最惯用方式

标签 scala

假设我有 4 个 future 的计算要做。前两个可以并行完成,但第三个必须在前两个之后完成(即使前两个的值未在第三个中使用——将每个计算视为执行某些数据库操作的命令)。最后,在所有前 3 个计算之后必须进行第 4 个计算。此外,还有一个副作用可以在前 3 个完成后开始(将其视为启动周期性可运行)。在代码中,这可能类似于以下内容:

for {
  _ <- async1     // not done in parallel with async2 :( is there
  _ <- async2     // any way of achieving this cleanly inside of for?
  _ <- async3
  _ =  sideEffect // do I need "=" here??
  _ <- async4
} yield ()

这些评论显示了我对代码质量的怀疑:

  1. 在 for comprehension 中并行执行两个操作的最干净的方法是什么?
  2. 有没有一种方法可以在没有那么多“_”字符的情况下实现这个结果(也不分配命名引用,至少在 sideEffect 的情况下)
  3. 执行此操作最干净、最惯用的方法是什么?

最佳答案

您可以使用 zip 组合两个 futures,包括 zip 本身的结果。您最终会得到包含元组的元组,但如果您对 Tuple2 使用中缀表示法,则很容易将它们分开。下面我为简洁定义了一个同义词 ~(这是解析器组合器库所做的,除了它的 ~ 是一个不同的类,其行为类似于 Tuple2).

作为 _ = 的替代方案,您可以将其移至 yield 中,或使用大括号和分号将其与以下语句组合。我仍然认为 _ = 更符合习惯,至少在 for 中有一个副作用语句是完全符合习惯的。

val ~ = Tuple2

for {
  a ~ b ~ c <- async1 zip
               async2 zip
               async3
  d <- { sideEffect; async4 }
} yield (a, b, c, d)

关于scala - 在 Scala 中混契约(Contract)步、异步和并行计算以理解 future 的最惯用方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23860638/

相关文章:

scala - 配置 Scalaxb SBT 插件生成的源代码位置

scala - 递归函数不返回 Int

string - 将 Seq[String] 转换为 String*

scala - Spark UDAF 与 ArrayType 作为 bufferSchema 性能问题

java - 无法处理大于 65535 个字符的字符串文字。编译器抛出 IllegalArgumentException

scala - 从 Akka 流中的 Future 创建背压

java - 带有按 LIFO 顺序提供的等待列表的信号量或锁

Scala:如何测试调用System.exit()的方法?

scala - 如何使用 Eclipse 调试 Scala 宏

scala - 如何在 Scala 中创建内部 DSL?