簡體   English   中英

在Scala中按順序組合任意數量的期貨

[英]Sequentially combine arbitrary number of futures in Scala

我是scala的新手,我嘗試在scala 2.10RC3中組合幾個Futures。 Futures應按順序執行。 在文檔Scala SIP14中定義方法, andThen定義以按順序執行Futures。 我用這種方法組合了幾個Futures (見下面的例子)。 我的期望是它打印6但實際上結果為0 我在這做錯了什么? 我有兩個問題:

首先,為什么結果為0 其次,我如何組合幾個Futures ,以便第二個Future執行不會在第一個Future完成之前開始。

val intList = List(1, 2, 3)

val sumOfIntFuture = intList.foldLeft(Future { 0 }) {
 case (future, i) => future andThen {
  case Success(result) => result + i 
  case Failure(e) => println(e)
 }
}

sumOfIntFuture onSuccess { case x => println(x) }

andThen是副作用。 它允許您指定在將來完成之后以及在用於其他之前要執行的某些操作。

使用地圖:

scala> List(1, 2, 3).foldLeft(Future { 0 }) {
     |  case (future, i) => future map { _ + i }
     | } onSuccess { case x => println(x) }
6

我喜歡這種通用方法:

trait FutureImplicits {

  class SeriallyPimp[T, V](futures: Seq[T]) {
    def serially(f: T => Future[V])(implicit ec: ExecutionContext): Future[Seq[V]] = {
      val buf = ListBuffer.empty[V]
      buf.sizeHint(futures.size)

      futures.foldLeft(Future.successful(buf)) { (previousFuture, next) =>
        for {
          previousResults <- previousFuture
          nextResult <- f(next)
        } yield previousResults += nextResult
      }
    }
  }

  implicit def toSeriallyPimp[T, V](xs: Seq[T]): SeriallyPimp[T, V] =
    new SeriallyPimp(xs)

}

然后混合上面的特性並像這樣使用它:

val elems: Seq[Elem] = ???
val save: Elem => Future[Result] = ???
val f: Future[Seq[Result]] = elems serially save

可以改進此代碼以保留輸入集合類型。 例如,請參閱文章。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM