在下面的代码x
中输入Future[Future[Int]]
,我需要将其展平为Future[Int]
。这怎么可能?
def times(a:Int, b:Int) = Future { a * b }
val x = for {
x1 <- Future { 1 }
x2 <- Future { 2 }
} yield {
val future = times(x1,x2)
future.map { result => result * 2 }
}
答案 0 :(得分:4)
使用相同的理解。当times
返回Future
时,输入x1
和x2
。您可以使用相同的理解来提取未来的价值。
def times(a:Int, b:Int) = Future { a * b }
val x = for {
x1 <- Future { 1 }
x2 <- Future { 2 }
result <- times(x1,x2)
} yield (result * 2)
请记住for-comprehension是flatMap
s和最终map
的语法糖
整件事可以写成
Future { 1 }.flatMap { x1 => Future { 2 }.flatMap { x2 => times(x1, x2).map { result => result * 2 }}}
警告:在创建数据独立期货内联时(在for-comprehension内或flatMap内)。这些期货将按顺序执行。
由于第一和第二期货是数据独立的。如果你在for-comprehension或flatMap之外创建它们,它们可以并行执行。
压扁期货
使用flatMap
将Future[Future[Int]]
转换为Future[Int]
def times(a:Int, b:Int) = Future { a * b }
val x = (for {
x1 <- Future { 1 }
x2 <- Future { 2 }
} yield {
val future = times(x1,x2)
future.map { result => result * 2 }
}).flatMap(identity) // <--- notice flatMap here around the for-comprehension
为清楚起见,上面的代码可以重写为
def times(a:Int, b:Int) = Future { a * b }
val x = for {
x1 <- Future { 1 }
x2 <- Future { 2 }
} yield times(x1,x2).map(_ * 2)
val finalResult = x.flatMap(identity)
scala> :paste
// Entering paste mode (ctrl-D to finish)
def times(a:Int, b:Int) = Future { a * b }
val x = for {
x1 <- Future { 1 }
x2 <- Future { 2 }
} yield times(x1,x2).map(_ * 2)
val finalResult = x.flatMap(x => x)
// Exiting paste mode, now interpreting.
scala> finalResult
res0: scala.concurrent.Future[Int] = Future(Success(4))