web-dev-qa-db-ja.com

Scalaで先物のリストを解決する方法

Futureを返す呼び出しがあります。ただし、n個のコールを行う必要があるため、n個のフューチャーを取得できます。先に進む前に(サーバーをブロックせずに)先物をすべて解決する方法を知りたいのですが

例えば、

while(counter < numCalls){
    val future = call(counter)
    future.map{  x =>
        //do stuff
    }
    counter += 1 
}

//Now I want to execute code here after ALL the futures are resolved without 
//blocking the server
22
user2816456

Future.sequence(futureList)を使用して、List[Future[X]]Future[List[X]]に変換できます。後者は単なるFutureなので、Await.readyまたは同様のヘルパーの助けを借りて、後者が完了するのを待つことができます。

したがって、生成する先物の一覧を保持する必要があります。何かのようなもの:

val futures = new ListBuffer[Future[X]]
while(counter < numCalls) {
    val future = call(counter)
    futures += future
    future.map { x =>
        //do stuff
    }
    counter += 1 
}
val f = Future.sequence(futures.toList)
Await.ready(f, Duration.Inf)

これは次のように書くこともできます。

val futures = (1 to numCalls).map(counter => {
    f = call(counter)
    f.map(x => ...)
    f
})
Await.ready(Future.sequence(futures), Duration.Inf)
52
Leo

もう少し機能的:

val futures = for {
  c <- 0 until 10
   } yield {
    val f = call(c) 
    f onSuccess {
      case x =>
      // Do your future stuff with x
    }
    f
  }
Future.sequence(futures)
6

先物が終わった後で何かをしたいと思います。元の呼び出しをブロックせずにコールバック?次に、このようなことをする必要があります:

val futures = for (...) yield {
  future {
  ...
  }
}

val f = Future sequence futures.toList

f onComplete {
  case Success(results) => for (result <- results) doSomething(result)
  case Failure(t) => println("An error has occured: " + t.getMessage)
}

http://docs.scala-lang.org/overviews/core/futures.html

したがって、await呼び出しでブロックすることはありませんが、すべてのFutureが完了するのを待ってから、すべての結果に対して何かを行います。重要な側面は、Future.sequenceを使用して多くのフューチャーを結合し、コールバックを使用して結果に作用することです。

5
wallnuss