【发布时间】:2016-05-10 13:47:17
【问题描述】:
假设我想汇总来自 2 个远程服务的数据,并尽可能快地提供响应:
def loadUser: Future[User]
def loadData: Future[Data]
case class Payload(user: User, data: Data)
我知道这个是按顺序执行异步任务的:
for {
user <- loadUser
data <- loadData
} yield Payload(user,data)
虽然这是并行执行它们,因为异步任务在被顺序链接之前被触发:
val userF = loadUser
val dataF = loadData
for {
user <- userF
data <- dataF
} yield Payload(user,data)
不过,这种区别对我来说有点太隐晦了,可能有人一开始没有注意到。
Applicatives 也能解决问题
(loadUser |@| loadData) { Payload(_,_) }
谁能告诉我,我宁愿在应用程序和 monad 之间使用什么来执行并行异步计算?每种方法的优缺点是什么?
【问题讨论】:
-
我认为,从根本上说,如果您需要 someComputationA 的输出来计算 someComputationB 的输出,则可以使用 monad。如果你只想计算两个独立的东西并将它们组合起来,applicative 就可以了。虽然这并不是关于应用程序的特别“并行”,但我认为由于上述原因,monads 本质上是顺序的。如果您需要真正的并行计算,monad 可能不是您正在寻找的结构。 挥手
-
我的回答here有一些相关的讨论。
-
并行运行
Future计算的标准习惯用法是zip:for ((user, data) <- loadUser zip loadData) yield Payload(user, data) -
你可能会发现这个discussion很有用。
标签: scala monads scalaz applicative scala-cats