如何在Scala中处理嵌套的期货序列函数

问题描述 投票:0回答:2

我想创建一个函数,该函数返回成功操作后的期货序列的结果。我遇到的问题是返回类型是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()
val square = squareGenerator.getSquare().onComplete({
  case Success(result) =>{
    //do something with result
  }
  case Failure(e){//log failure}
})
scala future
2个回答
0
投票

这里只是未来的回报

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
    }
  })

0
投票

而不是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内转换返回类型,并且只有成功完成后才能返回远期。

这就是为什么您需要添加recover来处理将来失败的情况。


0
投票

onComplete产生一个Unit。您需要mapflatMap或其他实际产生值的东西。

  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
    }
© www.soinside.com 2019 - 2024. All rights reserved.