当前位置: 首页 > 知识库问答 >
问题:

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

魏烨熠
2023-03-14

我想创建一个函数来返回成功操作的一系列期货的结果。我遇到的问题是返回类型为Unit,并且未来函数正在完成,而无需等待嵌套的未来序列完成。我尝试过不使用on完成函数,而是使用map或平面图,但没有成功。我还想避免使用wait

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

共有3个答案

张照
2023-03-14

回到这里的未来

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
    }
  })
宗政德宇
2023-03-14

< code>onComplete生成一个< code >单元。您想要< code>map或< code>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
    }
邹涵畅
2023-03-14

而不是在完成,你应该做:

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中转换返回类型,并且只有当它成功完成时,才会返回future。

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

如果您这样做,就不需要在函数的开头使用< code>Future,因为您不需要创建新的< code>Future -您将使用< code>results中的< code>Future。

 类似资料:
  • 我有两个在未来发生的计算,如下所示: 我希望它能够运行,以便comp2总是在comp1完成后运行!我知道使用一个表达,我可以组成这两个Future的喜欢。 什么能保证comp1在comp2之前完成?我的意思是这些是发生在不同线程中的计算,并且不能保证运行的顺序。有没有一种方法可以保证没有阻塞的顺序?

  • 问题内容: 我有一个Vendor对象,可以从一个单独的“ vendor” json序列中反序列化,但是我想将此序列反序列化为一个,我只是想不出如何让Jackson合作。有小费吗? 问题答案: 您的数据存在问题,因为您的数组中有内部 包装 对象。想必你的对象被设计成手柄,,,但每次的多个对象也都包裹在一个对象与单一属性。 我假设您正在使用Jackson 数据绑定 模型。 如果是这样,那么有两件事要考

  • Scala 函数 我们可以在 Scala 函数内定义函数,定义在函数内的函数称之为局部函数。 以下实例我们实现阶乘运算,并使用内嵌函数: object Test { def main(args: Array[String]) { println( factorial(0) ) println( factorial(1) ) println( factor

  • 我想把这个val: 对它进行一些操作(我正在考虑展平) 然后得到这个结果 如果展平方法在这里不合适,那很好。只要我得到结果。 谢啦!

  • 我正在与我无法控制的遗留库集成。 它定义了以下接口: 这个“subscribe”方法被不同的线程频繁调用。我关心“Future.get()”的结果的唯一情况是当它失败时,所以我可以获取并处理异常。这不一定发生在调用线程中。另外,在“Future.get()”上阻塞调用线程对我来说是非常昂贵的,因为即使成功也可能需要几秒钟才能完成。 所以我的任务是以某种方式“后处理”所有这些期货,过滤失败的期货。基

  • 假设我有一个抽象的“生产者”实例: 我需要对它产生的每个(或一些)对象进行一些处理。所以,我做了类似的事情: …并以<code>Future[Seq[Future[T]]]结束。这没关系,但有点麻烦。我想摆脱外部的,只需要就可以了,但我想不出一个(非阻塞)转换,可以让我这样做。 有什么想法吗?