2017-11-26 9 views
2

나는 Future[Iterator]입니다. 이 반복자를 내 스트림에 공급하고 싶습니다. 여기서, 나는 여전히 Source.fromIterator을 사용하는 것과 같이 Iterator에서 Source를 생성하려고합니다.Future [Iterator]에서 소스를 만드는 방법은 무엇입니까?

하지만 여기서는 미래로 인해 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)) 

답변

4

당신은 Source.fromFuture, flatMapConcatSource.fromIterator의 조합을 사용할 수 있습니다. 예 :

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

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

더하기, 우수한 팁. 이 방법에 대해 몰랐습니다. – oblivion

1

청주의 대답은 질문의 요구 사항과 가장 일치합니다.

난 그냥 일반적으로 이런 종류의 기능이 map 또는 flatMap 통해 다른 Future 내에서 수행되는 것을 지적하고 싶었 :

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) }