【问题标题】:Best way to accumulate futures积累期货的最佳方式
【发布时间】:2015-02-25 19:45:16
【问题描述】:

假设我有一个返回 Future 的函数,根据这个函数的结果,我可能需要再次调用它,或者我可能会立即返回。我需要将这些结果累积在一个列表中。我想定义一个将这个列表作为 Future 返回的函数。我有以下内容:

def foo: Future[Int] { ... }

def accum(i: Future[Int], l: List[Int]): Future[List[Int]] = i.map { i =>
    if (i >= max)
        l
    else 
        accum(foo, i :: l)
}

def test: Future[List[Int]] = accum(foo, List())

但这当然不会编译,因为在映射中调用 accum() 需要返回 List[Int] 而不是 Future[List[Int]]。这样做的正确方法是什么?

【问题讨论】:

    标签: scala akka


    【解决方案1】:

    始终从内部块返回Future,并使用flatMap

    def accum(i: Future[Int], l: List[Int]): Future[List[Int]] =
      i.flatMap { i =>
        if (i >= max)
          Future.successful(l)
        else 
          accum(foo, i :: l)
      }
    

    根据foo 的来源,您可能还需要考虑例如scalaz 的 foldLeftM 而不是显式的递归函数。

    【讨论】:

      【解决方案2】:

      我认为以下内容对你有用,

      def foo: Future[Int] = ???
      
      def accumulate( max: Int, f: () => Future[ Int ], list: List[ Int ] = List[ Int ]() ): Future[ List[ Int ] ] = {
        val intFuture = f()
      
        intFuture.flatMap( ( i: Int ) => {
          // if future is successfull
          if ( i < max ) {
            // If value less than max, keep on accumulating more 
            accumulate( max, f, list :+ i )
          }
          else {
            // If value not less than max, stop accumulating more
            // Just wrap the list in future and return
            val promiseOfList = Promise[ List[ Int ] ]()
            promiseOfList.complete( Success( list ) )
            promiseOfList.future
          }
        } ).fallbackTo( {
          // If this computation fails.... stop accumulating
          // Just wrap the list in future and return
          val promiseOfList = Promise[ List[ Int ] ]()
          promiseOfList.complete( Success( list ) )
          promiseOfList.future
        } )
      
      }
      
      val myListFuture = accumulate( max, foo )
      

      【讨论】:

        猜你喜欢
        • 2016-12-22
        • 1970-01-01
        • 1970-01-01
        • 2014-01-31
        • 1970-01-01
        • 2020-02-13
        • 2011-03-09
        • 2011-10-19
        • 1970-01-01
        相关资源
        最近更新 更多