2012-12-12 5 views
10

저는 scala에 익숙하지 않습니다. 2.10RC3에 몇 가지 Futures를 결합하려고합니다. Futures은 순차적 인 순서로 실행되어야합니다. 문서 Scala SIP14에서는 선물을 순차적으로 실행하기 위해 andThen 메서드가 정의됩니다. 이 방법을 사용하여 여러 개의 Futures을 결합했습니다 (아래 예 참조). 내 기대는 6을 인쇄했지만 결과는 0입니다. 여기서 내가 뭘 잘못하고 있니? 두 가지 질문이 있습니다.Scala에서 임의의 수의 미래를 순차적으로 결합합니다.

먼저, 결과가 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) } 

답변

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 문서를 참조하십시오.

관련 문제