【问题标题】:Understanding Iteratee in play framework理解 Iteratee in play 框架
【发布时间】:2016-01-09 15:22:58
【问题描述】:

以下是 Reactive Web Apps in Play 书中的一个示例:

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 的关于 cat 的帖子。但它是如何做到这一点的呢?我们没有向它传递任何东西。

【问题讨论】:

  • 似乎get 方法需要一个来自对Iteratee 的响应的函数,然后它在内部使用它。请参阅文档:playframework.com/documentation/2.3.x/api/scala/…get[A](consumer: (WSResponseHeaders) ⇒ Iteratee[Array[Byte], A])
  • 是的,我一分钟前才意识到这一点。谢谢!你能写一个答案吗?我会很乐意接受! :)

标签: scala playframework


【解决方案1】:

get 方法需要一个从响应到Iteratee 的函数,然后它在内部使用它。请参阅文档:

https://www.playframework.com/documentation/2.3.x/api/scala/index.html#play.api.libs.ws.WSRequestHolder

和源代码(这里:https://github.com/playframework/playframework/blob/2.3.x/framework/src/play-ws/src/main/scala/play/api/libs/ws/WS.scala

/**
 * 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-04-27
    • 1970-01-01
    • 2020-05-19
    • 2012-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多