0

我正在尝试从 Play 2.1.3 升级到 2.2.0,但在尝试编译时出现错误。主要的变化是 play.api.libs.concurrent.Promise 已被弃用,并被指示用 scala.concurrent.Promise 替换它。编译错误如下:

错误信息:

WebSocketJoin.scala:23: object creation impossible, since method fold in trait Iteratee of type [B](folder: play.api.libs.iteratee.Step[A,B] => scala.concurrent.Future[B])(implicit ec: scala.concurrent.ExecutionContext)scala.concurrent.Future[B] is not defined
[error]         def wrap(delegate: Iteratee[A, B]): Iteratee[A, B] = new Iteratee[A, B] {
[error]                                                                  ^
[error] one error found
[error] (adapter-api/compile:compile) Compilation failed

代码:

package utils

import play.api.libs.iteratee.{Step, Enumerator, Iteratee}
import scala.concurrent.{Promise, ExecutionContext, Future}
import ExecutionContext.Implicits.global

object WebSocketJoin {

  /**
   * Create a joined iteratee enumerator pair.
   *
   * When the enumerator is applied to an iteratee, the iteratee subsequently consumes whatever the iteratee in the pair
   * is applied to.  Consequently the enumerator is "one shot", applying it to subsequent iteratees will throw an
   * exception.
   */
  def joined[A]: (Iteratee[A, Unit], Enumerator[A]) = {
    val promisedIteratee = Promise[Iteratee[A, Unit]]()
    val enumerator = new Enumerator[A] {
      def apply[B](i: Iteratee[A, B]) = {
        val doneIteratee = Promise[Iteratee[A, B]]()

        // Equivalent to map, but allows us to handle failures
        def wrap(delegate: Iteratee[A, B]): Iteratee[A, B] = new Iteratee[A, B] {
          def fold[C](folder: (Step[A, B]) => Future[C]) = {
            val toReturn = delegate.fold {
              case done @ Step.Done(a, in) => {
                doneIteratee.success(done.it)
                folder(done)
              }
              case Step.Cont(k) => {
                folder(Step.Cont(k.andThen(wrap)))
              }
              case err => folder(err)
            }
            toReturn.onFailure {
              case e => doneIteratee.failure(e)
            }
            toReturn
          }
        }

        if (promisedIteratee.trySuccess(wrap(i).map(_ => ()))) {
          doneIteratee.future
        } else {
          throw new IllegalStateException("Joined enumerator may only be applied once")
        }
      }
    }
    (Iteratee.flatten(promisedIteratee.future), enumerator)
  }
}
4

1 回答 1

5

我在博客文章中发布的加入的迭代器/枚举器对现在可以在 Play 2.2.0 中以play.api.libs.iteratee.Concurrent.joined. 切换到那个,你可以从你的代码库中删除上面的代码。

顺便说一句,要修复您的代码,请修改第 24 行的方法以接受隐式 ExecutionContext。Play 2.2 改变了 iteratee API,现在很多东西都接受异常上下文:

def fold[C](folder: (Step[A, B]) => Future[C])(implicit ec: ExecutionContext) 
于 2013-09-25T04:24:29.577 回答