在屏幕上编写并输出两个未来的异步操作

时间:2017-05-28 19:52:48

标签: scala asynchronous playframework action future

我讨厌问 - 我真的这么做但是这个人暂时让我...

我尝试用 Play Framework & scala 撰写一些动作我的主要导游是this vid。然而它是在几年前制作的,因此一些功能已被弃用,因此我不得不在我去的时候找到解决方法。目前我正在尝试在某些HTML标记中输出两个异步操作。

我用这个控制器成功输出了一个动作:

package controllers

import akka.actor.ActorSystem
import javax.inject._
import play.api.mvc._
import services.ServiceClient
import scala.concurrent.ExecutionContext

@Singleton
class AsyncController @Inject() (sc: ServiceClient)(actorSystem: ActorSystem)(implicit exec: ExecutionContext) extends Controller {

  def index = Action.async { request =>

    val asy1 = sc.makeServiceCall("async1")

    for {
      async1Message <- asy1
    } yield {
      Ok(views.html.async1.async1(async1Message))
    }
  }

}

如果您想知道sc.makeServiceCall引用此文件:

class ServiceClient @Inject() (ws: WSClient) {

  def makeServiceCall(serviceName: String): Future[String] = {
    ws.url(s"http://localhost:9000/mock/$serviceName").get().map(_.body)
  }

}

所以我按照其中的视频进行了跟踪。使用某些HTML编写两个异步操作的指南。这就是困难/有趣/令人不安的地方:

package controllers

import javax.inject.Inject
import akka.actor.ActorSystem
import play.api.mvc._
import scala.concurrent.{ExecutionContext}
import Ui.Pagelet

class AsyncHomeController @Inject() (as1: AsyncController)(as2: Async2Controller)(actorSystem: ActorSystem)(implicit exec: ExecutionContext) extends Controller {

  def index = Action.async { request =>

    val asy1 = as1.index(request)
    val asy2 = as2.index(request)

    for {
      async1Result <- asy1
      async2Result <- asy2

      async1Body <- Pagelet.readBody(async1Result)
      async2Body <- Pagelet.readBody(async2Result)

    } yield {
      Ok(views.html.home2(async1Body, async2Body))
    }
  }

}

因此Async2ControllerAsyncController非常相似,Pagelet.readBody指的是:

package Ui

import play.api.libs.iteratee.Iteratee
import play.api.mvc.{Codec, Result}
import play.twirl.api.Html
import scala.concurrent._

object Pagelet {

  def readBody(result: Result)(implicit codec: Codec): Future[Html] = {
    result.body.run(Iteratee.consume()).map(bytes => Html(new String(bytes, codec.charset)))
  }

}

这就是错误所在 - 这就是:

  

值run不是play.api.http.HttpEntity

的成员

我无法找到有关是否需要注入的文档或任何已被弃用的迹象。 如果有人得到了答案或解决方法,请透露。非常感谢

1 个答案:

答案 0 :(得分:0)

Iteratee lib已弃用,已替换为akka-stream。您需要更改readBody的实现:

def readBody(result: Result)(implicit mat: Materializer, ec: ExecutionContext, codec: Codec): Future[Html] = {
  result.body.consumeData.map(byteString => Html(codec.decode(byteString))
}

您还需要更改控制器的依赖关系以获得Materializer

class AsyncHomeController @Inject() (as1: AsyncController, as2: Async2Controller)(actorSystem: ActorSystem)(implicit exec: ExecutionContext, mat: Materializer)

编辑:代码已更新