3

Playframework に小さな Scala プロジェクトがあります。私はすべてを反応的にやろうとしていますが、問題に遭遇しました。

日付順に並べられた DB の値を表す 2 つの Enumerator[A] インスタンスがあります。日付の順序を維持する単一の Enumerator[A] としてそれらを返す必要があります。Enumerator[A] でその解決策を見つけられなかったので、A を単一のコレクションに蓄積し、後で並べ替えています。

case class A(
   created: Date,
   data: String
)

val as: Enumerator[A] = findByAOrderedByCreated()
val bs: Enumerator[A] = findByBOrderedByCreated()

これに対処するための反応的な方法は何ですか?

4

1 に答える 1

2

要素の any を使用して、任意の数の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たそれぞれに適用すると、ソートされた要素を与える を作成します。インスタンスと は、互いにインスタンスを送信することによって通信します (したがって、 theなど)。EnumeratorEnumeratorIterateeEnumeratorPromisePromise[Promise[IterateeReturn]]

于 2014-04-16T20:22:47.867 に答える