顺序结合在斯卡拉期货的任意数(Sequentially combine arbitrary numb

2019-08-03 23:27发布

我是新来的Scala和我尝试几个期货斯卡拉2.10RC3结合。 该Futures应该按顺序执行。 在该文件中的Scala SIP14的方法andThen ,以便按顺序执行期货定义。 我用这个方法来几个结合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) }

Answer 1:

andThen为副作用。 它允许你指定一些未来的行动结束后做,它用于别的东西了。

使用地图:

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


Answer 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

这段代码可以改进以保持输入集合类型。 请参见本文章的例子。



文章来源: Sequentially combine arbitrary number of futures in Scala