這裏是一個解決方案,將使用對元件的任何Ordering
任何數量Enumerator
值的工作:
import play.api.libs.iteratee._
import scala.concurrent._
object MergeEnums {
def apply[E: Ordering](enums: Enumerator[E]*)(implicit executor: ExecutionContext) = new Enumerator[E] {
def apply[A](iter: Iteratee[E, A]) = {
case class IterateeReturn(o: Option[(Promise[Promise[IterateeReturn]], E)])
val failP = Promise()
val failPF = failP.future
val initState = Future.traverse(enums) { enum =>
val p = Promise[IterateeReturn]()
enum.run(Iteratee.foldM(p) { (oldP: Promise[IterateeReturn], elem: E) =>
val p = Promise[Promise[IterateeReturn]]()
oldP success IterateeReturn(Some(p, elem))
p.future
} map { promise =>
promise success IterateeReturn(None)
}) onFailure { case t => failP failure t }
p.future
} map (_.map(_.o).flatten.toList)
Enumerator.unfoldM(initState) { fstate =>
Future.firstCompletedOf(Seq(fstate, failPF)) map { state =>
state.sortBy(_._2) match {
case Nil => None
case (oldP, elem) :: tail =>
val p = Promise[IterateeReturn]()
oldP success p
val newState = p.future.map(_.o.map(_ :: tail).getOrElse(tail))
Some(newState, elem)
}
}
} apply iter
}
}
}
它創建一個Iteratee
適用於傳遞在每個Enumerator
和Enumerator
到給排序的元素。 Iteratee
實例和Enumerator
通過向對方發送Promise
實例(因此是Promise[Promise[IterateeReturn]]
等)進行通信。
不錯的解決方案:) –
謝謝:)這意味着許多來自Play技術領導。 – wingedsubmariner
對不起,花了我一大筆時間才終於開始使用它 – mavarazy