[英]Dependent futures
开始玩Scala期货,我陷入了依赖期货的困境。
我们来举个例子。 我搜索地点并获得Future[Seq[Place]]
。 对于每个地方,我搜索最近的地铁站(该服务重新开始Future[List[Station]]
)。
我会写这个:
Place.get()
.map { places =>
places.map { place =>
Station.closestFrom(place).map { stations =>
SearchResult(place, stations)
}
}
}
那件事会让我得到一个Future[Seq[Future[SearchResult]]]
......这不是我所期待的。
我错过了什么来获得Future[Seq[SearchResult]]
?
谢谢大家,
阿尔班
您在解决方案中缺少两个Future
概念: flatMap
和Future.sequence
解释每个:
flatMap
就像map
一样,除了从future.map(A => B)
给它一个函数,你从future.flatMap(A => Future[B])
给它一个函数future.flatMap(A => Future[B])
。 这样你就可以将期货连在一起了。
Future.sequence
是一个辅助函数,它将期货列表与列表的未来结合起来: Seq[Future[A]] => Future[Seq[A]]
使用Future
API的这两个功能,我们可以将您的答案更改为:
Place.get().flatMap { places =>
Future.sequence(places.map { place =>
Station.closestFrom(place).map { stations =>
SearchResult(place, stations)
}
})
}
使用for-understand进行使用期望通常更容易,而不是直接映射/ flatMap。 在你的情况下,它应该是这样的:
for {places <- Place.get()
searchResults <- Future.traverse(places)(place => for (stations <- Station.closestFrom(place))
yield SearchResult(place,stations)
)
} yield searchResults
Future
是一个单子,它为您提供了几种连接您的运营方式。
f : A => B
到框内的myfuture : Future[A]
,确实是map
是获得Future[B]
。 但是在目前情况下, Station.closestFrom
a没有给你一个List[Stattion]
而是一个Future[List[Station]]
。 h : A => Future[B]
或链接其中几个(这里是Places.get
和Station.closestFrom
), flatMap
就是你要走的路。 将h
应用于Future[A]
为您提供Future[B]
。 h : A => Future[B]
到类似places : Seq[A]
的集合places : Seq[A]
,你应该使用Future.traverse : Seq[A] => (A => Future[B]) => Future[Seq[B]]
。 此外,Scala的for-compresention只是flatMap / map的语法糖,所以不用直接使用它们编写复杂的代码,你可以使用干净清晰的for循环。 循环:
for { variable1 <- f1
variable2 <- f2
} yield expression
相当于(没有优化):
f1.flatMap( variable1 => f2.map(variable2 => expression))
不要犹豫使用for-understanding,它确实有帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.