我正在尝试从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)
}
}
答案 0 :(得分:5)
我在博客文章中发布的已加入的iteratee / enumerator对现在在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)