如何从Future [Iterator]创建一个来源?

时间:2017-11-26 12:55:39

标签: scala stream akka akka-stream

我有Future[Iterator]。我想将这个迭代器提供给我的Stream。在这里,我仍然想要像使用Source.fromIterator一样从Iterator构造一个Source。

但是,由于Future,我不能在这里使用Source.fromIterator

也许我可以使用Source.fromFuture但是当我尝试使用它时,在我的情况下它实际上似乎并没有从Iterator创建一个Source。来自文档:

/**
   * Starts a new `Source` from the given `Future`. The stream will consist of
   * one element when the `Future` is completed with a successful value, which
   * may happen before or after materializing the `Flow`.
   * The stream terminates with a failure if the `Future` is completed with a failure.
   */
  def fromFuture[T](future: Future[T]): Source[T, NotUsed] =
    fromGraph(new FutureSource(future))

2 个答案:

答案 0 :(得分:5)

您可以使用Source.fromFutureflatMapConcatSource.fromIterator的组合。例如:

val futIter = Future(Iterator(1, 2, 3))

val source: Source[Int, _] =
  Source.fromFuture(futIter).flatMapConcat(iter => Source.fromIterator(() => iter))

答案 1 :(得分:1)

Chunjef的答案最符合问题的要求。

我只是想指出,通常这种功能是通过Futuremap在另一个flatMap内完成的:

type Data = ???

val iterFuture : Future[Iterator[Data]] = ???

val dataSeq : Future[Seq[Data]] = iterFuture flatMap { iter =>
  Source
    .fromIterator(() => iter)
    .to(Sink.seq[Data])
    .run()
}

如果您根本不想使用流,还有Future.traverse功能:

type OutputData = ???

val someCalculation : Data => Future[OutputData] = ???

val outputIterFuture : Future[Iterator[OutputData]] = 
  iterFuture flatMap { iter => Future.traverse(iter)(someCalculation) }