如何在 Scala 中处理嵌套的 Futures Sequence 函数
How to handle nested Futures Sequence functions in Scala
我想创建一个函数,该函数 return 是成功操纵的一系列期货的结果。我遇到的问题是 return 类型是 Unit 并且 future 函数正在完成而无需等待嵌套的 future 序列完成。我试过不使用 onComplete 函数而是使用 map 或 flatMap 但没有成功。我也想避免使用 await
class SquareGenerator(){
//if type is changed to Unit anything that calls this function receives a empty success
def getSquare() : Future[Int] = Future{
val sums = List(future1(), future2())
val results = Future.sequence(sums)
//compiler throws an error because this is returning a unit
results.onComplete({
case Success(result) =>{
val sum = result(0) + result(1)
sum * sum
}
})
}
private def future1() : Future[Int] = Future{
//do something that takes time
2
}
private def future2() : Future[Int] = Future{
//do something that takes time
3
}
}
以后会这样称呼
val squareGenerator = new SquareGenerator()
squareGenerator.getSquare().onComplete({
case Success(result) =>{
//do something with result
}
case Failure(e){//log failure}
})
只是return这里的未来
def getSquare : Future[Future[List[Int]]] = Future{
val sums = List(future1(), future2())
Future.sequence(sums)
}
并且,当您调用它时,检查结果的完成
squareGenerator.getSquare.onComplete({
case Success(result) =>
result.onComplete({
case Success(result) => {
val sum = result(0) + result(1)
val square = sum * sum
println(square)
}
})
case Failure(e) => {
//log failure
}
})
而不是 onComplete
你应该这样做:
results.map{ result =>
val sum = result(0) + result(1)
sum * sum
}.recover { case e => ...
// write to log, throw e, or return the same type of sum
}
用map
可以转换Future
里面的return类型,以后只有成功完成才会returned。
这就是为什么你需要添加 recover
来处理 future 失败的情况。
如果你这样做,你将不需要函数开头的 Future
,因为你不需要创建一个新的 Future
- 你将使用 Future
来自 results
.
onComplete
生成 Unit
。您想要 map
或 flatMap
或其他实际产生值的东西。
def getSquare() : Future[Int] = {
val sums = List(future1(), future2())
val results: Future[List[Int]] = Future.sequence(sums)
results.map {
result =>
val sum = result(0) + result(1)
sum * sum
}
}
使用数组索引不安全。为了安全起见,您可以使用折叠或模式匹配。
results map {
case m :: n :: Nil =>
val sum = m + n
sum * sum
case _ =>
println("did not get 2 numbers!")
0
}
你应该使用 map/flatmap 或理解。
def getSquare() : Future[Int] =
for {
res1 <- future1()
res2 <- future2()
} yield {
val sum = res1 + res2
sum * sum
}
for comprehension
是 map 和 flatmap 的便捷包装。在 for
部分,您需要将期货结果分配给变量,稍后您可以在 yield
部分对它们进行操作。
我想创建一个函数,该函数 return 是成功操纵的一系列期货的结果。我遇到的问题是 return 类型是 Unit 并且 future 函数正在完成而无需等待嵌套的 future 序列完成。我试过不使用 onComplete 函数而是使用 map 或 flatMap 但没有成功。我也想避免使用 await
class SquareGenerator(){
//if type is changed to Unit anything that calls this function receives a empty success
def getSquare() : Future[Int] = Future{
val sums = List(future1(), future2())
val results = Future.sequence(sums)
//compiler throws an error because this is returning a unit
results.onComplete({
case Success(result) =>{
val sum = result(0) + result(1)
sum * sum
}
})
}
private def future1() : Future[Int] = Future{
//do something that takes time
2
}
private def future2() : Future[Int] = Future{
//do something that takes time
3
}
}
以后会这样称呼
val squareGenerator = new SquareGenerator()
squareGenerator.getSquare().onComplete({
case Success(result) =>{
//do something with result
}
case Failure(e){//log failure}
})
只是return这里的未来
def getSquare : Future[Future[List[Int]]] = Future{
val sums = List(future1(), future2())
Future.sequence(sums)
}
并且,当您调用它时,检查结果的完成
squareGenerator.getSquare.onComplete({
case Success(result) =>
result.onComplete({
case Success(result) => {
val sum = result(0) + result(1)
val square = sum * sum
println(square)
}
})
case Failure(e) => {
//log failure
}
})
而不是 onComplete
你应该这样做:
results.map{ result =>
val sum = result(0) + result(1)
sum * sum
}.recover { case e => ...
// write to log, throw e, or return the same type of sum
}
用map
可以转换Future
里面的return类型,以后只有成功完成才会returned。
这就是为什么你需要添加 recover
来处理 future 失败的情况。
如果你这样做,你将不需要函数开头的 Future
,因为你不需要创建一个新的 Future
- 你将使用 Future
来自 results
.
onComplete
生成 Unit
。您想要 map
或 flatMap
或其他实际产生值的东西。
def getSquare() : Future[Int] = {
val sums = List(future1(), future2())
val results: Future[List[Int]] = Future.sequence(sums)
results.map {
result =>
val sum = result(0) + result(1)
sum * sum
}
}
使用数组索引不安全。为了安全起见,您可以使用折叠或模式匹配。
results map {
case m :: n :: Nil =>
val sum = m + n
sum * sum
case _ =>
println("did not get 2 numbers!")
0
}
你应该使用 map/flatmap 或理解。
def getSquare() : Future[Int] =
for {
res1 <- future1()
res2 <- future2()
} yield {
val sum = res1 + res2
sum * sum
}
for comprehension
是 map 和 flatmap 的便捷包装。在 for
部分,您需要将期货结果分配给变量,稍后您可以在 yield
部分对它们进行操作。