连续的条件未来调用(在Play Scala服务器中)无法正常工作

时间:2017-09-28 17:12:10

标签: scala playframework async-await future

我使用以下代码从我的Play Scala应用服务器(2.5.x)中的远程站点获取新闻。我正在使用" https://www.playframework.com/documentation/2.5.x/ScalaWS"建议的机制。 用例分为两个步骤:

  1. 使用缓存令牌调用远程API-2以获取新闻内容。
  2. 如果令牌无效/已过期,请调用远程API-1以获取令牌并对其进行缓存。
  3. 问题:即使缓存的令牌有效,我也无法避免步骤#2。因此,我为Action中的listRemoteNews的每次调用提取令牌。

    如果我使用if-else条件,那么我会收到如下编译错误。请注意,我也尝试过理解,但我仍然需要在那里使用if条件。然后我得到相同的编译错误。

    [error] /sandbox/git/play-scala-app.repo/app/controllers/remoteapi/ListRemoteNewsController.scala:26: overloaded method value async with alternatives:
    [error]   [A](bodyParser: play.api.mvc.BodyParser[A])(block: play.api.mvc.Request[A] => scala.concurrent.Future[play.api.mvc.Result])play.api.mvc.Action[A] <and>
    [error]   (block: play.api.mvc.Request[play.api.mvc.AnyContent] => scala.concurrent.Future[play.api.mvc.Result])play.api.mvc.Action[play.api.mvc.AnyContent] <and>
    [error]   (block: => scala.concurrent.Future[play.api.mvc.Result])play.api.mvc.Action[play.api.mvc.AnyContent]
    [error]  cannot be applied to (scala.concurrent.Future[Any])
    [error]    def listRemoteNews = Action.async {
    

    下面的代码部分(requestOnerequestTwo是形成WSRequest并返回Future[WSResponse])的方法:

    @Singleton
    class ListRemoteNewsController @Inject()(ws: WSClient)(implicit context: ExecutionContext) extends Controller {
       def listRemoteNews = Action.async {
          println("<--- Stored Token 1: " + remoteToken)
          val responseTwo: Future[WSResponse] = requestTwo.withQueryString("token" -> remoteToken).get()
          val resp: Future[JsValue] = responseTwo.map {
             response =>
                   response.json
          }
          resp.map {
             response => {
                Ok(response)
             }
          }
    
          println("<-- Get token...")
          val responseOne: Future[WSResponse] = requestOne
          val resp2: Future[String] = responseOne.map {
             response => {
                remoteToken = (response.json  \ "token_list" \ "token").as[String]
                println("<--- Obtained token 2: " + remoteToken)
                remoteToken
             }
          }
    
          val responseThree: Future[WSResponse] = requestTwo.withQueryString("token" -> remoteToken).get()
          responseThree.map {
             response => {
                println("<--- status: " + response.status)
                Ok(response.json)
             }
    
          }
       }
    

1 个答案:

答案 0 :(得分:0)

期货是必须组成的东西。现在,你正在做出许多不同的请求,每个请求都返回期货,但你不会以任何方式返回这些期货或将它们组合在一起。如果你不对地图功能返回的新未来做任何事情,那么绘制未来是没有意义的。

您需要做的是撰写未来,这是使用<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <select id="mainDD" name="main" data-placeholder="Choose" class="chzn-select" style="width:600px;"> <option value="1">1</option> <option value="2">2</option> <option value="3">3</option> </select> <select name="type" id=type1> <option value="1">1</option> <option value="2">2</option> </select> <form id="postform" action="http://localhost:8000/app/test_view" method="POST"> <input type="submit" value="SEND"> </form>等方法完成的。

所以这里大致是我猜你的代码应该是这样的:

flatMap

如果上述内容没有任何意义,那么我建议你在做其他任何事情之前停下来阅读Scala期货。

以下是我通过Google快速搜索找到的一系列教程:

http://code.hootsuite.com/introduction-to-futures-in-scala/ https://danielasfregola.com/2015/04/01/how-to-compose-scala-futures/ https://doc.akka.io/docs/akka/current/scala/futures.html