我正在尝试从 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)
}
}