在以下两个函数中,someF1
将不编译,而someF2
将编译。这是因为预期someF1
将返回Future[Int]
,但由于我在Future[Future[Int]]
中使用了for
,所以它返回了for
。我不会在someF2
中遇到问题,因为我正在Future[Future[]]
中将someF2
展平。如果我使用嵌入式for
或someF1
是for
的错误用例,并且我应该仅使用它并行执行Futures
不按顺序?
// Start writing your ScalaFiddle code here
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
def someF1:Future[Int] = {
val f1 = Future[Int]{1}
for(i<-f1) yield{
if(i == 0) {
val f2 = Future{2}
for(j<-f2) yield {i+j} //this will make function return Future[Future[Int]]
}
else {
val f3 = Future{3}
for(k<-f3) yield {i+k}//this will make function return Future[Future[Int]]
}
}
}
// Start writing your ScalaFiddle code here
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
def someF2:Future[Int] = {
val f1 = Future[Int]{1}
f1.flatMap{i=> //flatMap will flatten Future[Future[Int]]
if(i == 0) {
val f2 = Future{2}
f2.map(j=> {i+j})
}
else {
val f3 = Future{3}
f3.map(k=>{i+k})
}
}
}
答案 0 :(得分:2)
规则是,通过理解for
,最终生成器(即<-
)将转换为map()
调用。每个其他生成器都是一个flatMap()
调用。因此,不,使用嵌套的for
后,您将无法实现自己的目标。这样会产生过多的map()
个呼叫,而不会产生flatMap()
个呼叫。
这将起作用:
def someF1:Future[Int] = {
val f1 = Future[Int]{1}
for {
i <- f1
j <- Future(2)
k <- Future(3)
} yield {
if (i == 0) i+j
else i+k
}
}
但是在这种情况下,您发射的Future
比实际需要的多。
答案 1 :(得分:1)
补充@jwvh的答案
您仍然可以使用以下更复杂的代码段来避免第二次以后的评估:
def someF1:Future[Int] =
for {
i <- Future[Int]{1}
r <- if (i == 0) {
for (j <- Future[Int]{2}) yield i + j
} else {
for (k <- Future[Int]{3}) yield i + k
}
} yield r
此外,我建议您看看documentation of for/yield