2012-12-12 6 views
10

私はscalaを使い慣れていません。いくつかの先物をscala 2.10RC3に結合しようとしています。 Futuresは、順番に実行する必要があります。文書Scala SIP14では、先物を順番に実行するために、方法andThenが定義されています。私はこの方法をいくつか組み合わせてFutures(以下の例を参照)を組み合わせました。私の期待は、それが6を印刷することでしたが、実際には結果は0です。私はここで間違って何をしていますか?私は2つの質問を持っています:Scalaの任意の数の先物を順番に結合します

最初に、なぜ結果は0ですか?第2に、複数のFuturesをどのように組み合わせて、Futureが完了する前に2番目の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) } 

答えて

12

andThenは、副作用のためです。これは、将来完了した後、そしてそれが他の目的のために使用される前に行うアクションを指定することを可能にします。

使用マップ:

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

ありがとうございます!これはまさに私が必要としていたものです。 – Chrisse

+0

+1これは私を大いに助けました! – pvorb

2

私はこの一般的なアプローチを好む:

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 

このコードは可能性入力収集タイプを保持するように改善する必要があります。たとえば、thisの記事を参照してください。

関連する問題