我有一个方法可以查找几个数据库并执行一些逻辑。
我从方法返回的MyType
对象如下:
case class MyResultType(typeId: Long, type1: Seq[Type1], type2: Seq[Type2])
方法定义如下:
def myMethod(typeId: Long, timeInterval: Interval) = async {
// 1. check if I can find an entity in the database for typeId
val myTypeOption = await(db.run(findMyTypeById(typeId))) // I'm getting the headOption on this result
if (myTypeOption.isDefined) {
val anotherDbLookUp = await(doSomeDBStuff) // Line A
// the interval gets split and assume that I get a List of thse intervals
val intervalList = splitInterval(interval)
// for each of the interval in the intervalList, I do database look up
val results: Seq[(Future[Seq[Type1], Future[Seq[Type2])] = for {
interval <- intervalList
} yield {
(getType1Entries(interval), getType2Entries(interval))
}
// best way to work with the results so that I can return MyResultType
}
else {
None
}
}
现在,getType1Entries(interval)
和getType2Entries(interval)
每个都会返回Future
个Seq(Type1)
和Seq(Type2)
条目!
我现在的问题是从Seq(Type1)
中取出Seq(Type2)
和Future
并将其填入MyResultType
案例类?
答案 0 :(得分:2)
你可以参考你提出的这个问题
Scala transforming a Seq with Future
所以你得到了
val results2: Future[Seq([Iterable[Type1], [Iterable[Type2])] = ???
然后打电话等待它,你根本就没有Futures
,你可以做你想做的事。
我希望我能正确理解这个问题。
哦,顺便说一句,你应该映射myTypeOption
而不是检查它是否已定义,如果不是<{p}则返回None
if (myTypeOption.isDefined) {
Some(x)
} else {
None
}
可以简单地替换为
myTypeOption.map { _ => // ignoring what actually was inside option
x // return whatever you want, without wrapping it in Some
}
答案 1 :(得分:0)
如果我理解你的问题,那么这应该可以解决问题。
def myMethod(typeId: Long, timeInterval: Interval): Option[Seq[MyResultType]] = async {
// 1. check if I can find an entity in the database for typeId
val myTypeOption = await(db.run(findMyTypeById(typeId))) // I'm getting the headOption on this result
if (myTypeOption.isDefined) {
// the interval gets split and assume that I get a List of thse intervals
val intervalList = splitInterval(interval)
// for each of the interval in the intervalList, I do database look up
val results: Seq[(Future[Seq[Type1]], Future[Seq[Type2]])] = for {
interval <- intervalList
} yield {
(getType1Entries(interval), getType2Entries(interval))
}
// best way to work with the results so that I can return MyResultType
Some(
await(
Future.sequence(
results.map{
case (l, r) =>
l.zip(r).map{
case (vl, vr) => MyResultType(typeId, vl, vr)
}
})))
}
else {
None
}
}
答案 2 :(得分:0)
您的问题有两个部分,1)如何处理两个相关的未来,以及2)如何提取结果值。
在处理从属期货时,我通常会将它们组合在一起:
val future1 = Future { 10 }
val future2 = Future { 20 }
// results in a new future with type (Int, Int)
val combined = for {
a <- future1
b <- future2
} yield (a, b)
// then you can use foreach/map, Await, or onComplete to do
// something when your results are ready..
combined.foreach { ((a, b)) =>
// do something with the result here
}
要提取结果,我通常使用Await
如果我需要进行同步响应,如果我需要处理潜在的失败,请使用_.onComplete()
,并使用_.foreach()
/ {{1对于大多数其他情况。