以下是Play书中的Reactive Web Apps的示例:
package controllers
import play.api._
import play.api.libs.iteratee.Iteratee
import play.api.libs.oauth.{OAuthCalculator, RequestToken, ConsumerKey}
import play.api.Play.current
import play.api.libs.ws.WS
import play.api.mvc._
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
class Application extends Controller {
val loggingIteratee = Iteratee.foreach[Array[Byte]] {
array => Logger.info(array.map(_.toChar).mkString)
}
def tweets = Action.async {
val credentials: Option[(ConsumerKey, RequestToken)] = for {
apiKey <- Play.configuration.getString("twitter.apiKey")
apiSecret <- Play.configuration.getString("twitter.apiSecret")
token <- Play.configuration.getString("twitter.token")
tokenSecret <- Play.configuration.getString("twitter.tokenSecret")
} yield (
ConsumerKey(apiKey, apiSecret),
RequestToken(token, tokenSecret)
)
credentials.map {
case (consumerKey, requestToken) => WS.url("https://stream.twitter.com/1.1/statuses/filter.json")
.sign(OAuthCalculator(consumerKey, requestToken))
.withQueryString("track" -> "cat")
.get {
response =>
Logger.info("Status: " + response.status)
loggingIteratee
}
.map(response => Ok("Stream closed"))
} getOrElse {
Future {
InternalServerError("Twitter credentials missing")
}
}
}
def index = Action {
Ok(views.html.index("Your new application is ready."))
}
}
我很难理解悬挂线:
loggingIteratee
在这种情况下,它似乎记录了关于来自twitter的猫的帖子。但它是如何实现的呢?我们没有传递任何东西。
答案 0 :(得分:1)
get
方法需要响应Iteratee
的函数,然后在内部使用它。见文档:
/**
* performs a get
* @param consumer that's handling the response
*/
def get[A](consumer: WSResponseHeaders => Iteratee[Array[Byte], A])(implicit ec: ExecutionContext): Future[Iteratee[Array[Byte], A]] = {
getStream().flatMap {
case (response, enumerator) =>
enumerator(consumer(response))
}
}
因此它基本上通过此Iteratee