我们在 Playframework 上有一个小型 Scala 项目。我试图做所有反应性的事情,并偶然发现了一个问题。
我有两个 Enumerator[A] 实例,表示按日期排序的数据库中的值。
我需要将它们作为单个枚举器 [A] 返回,保持日期排序。我在 Enumerator[A] 中没有找到任何解决方案,因此我在单个集合中累积 A,然后对它们进行排序。
case class A(
created: Date,
data: String
)
val as: Enumerator[A] = findByAOrderedByCreated()
val bs: Enumerator[A] = findByBOrderedByCreated()
处理这个问题的反应方式是什么?
这是一个适用于任意数量的解决方案Enumerator
使用任何值Ordering
关于元素:
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]]
等等)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)