[英]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.