【问题标题】:How to pass a Future data to the view?如何将 Future 数据传递给视图?
【发布时间】:2018-12-29 00:38:21
【问题描述】:

我正在尝试从 Web 天气 API 获取数据,我正在使用 WSClient 获取数据。

实际上,我可以像这样打印和可视化数据:

val futureResponse: Future[WSResponse] = complexRequest.get()

def weather = Action {
   futureResponse.map {
     response =>
       println(response.json)
   }
   println(futureResponse)

   Ok(views.html.weather("data"))
}

但我无法使用 Ok(views.html.weather("data")) 将其传递给视图层,因为当我 println(futureResponse) 它显示的不是 json 数据时: Future(Success(AhcWSResponse(StandaloneAhcWSResponse(200, OK))))

只有println(response.json) 显示了我想要发送但外部无法访问的有效数据。

【问题讨论】:

  • 您应该使用Action.async 并在Future.map 中应用视图

标签: scala playframework


【解决方案1】:

你需要一些东西

def weather = Action.async {
   complexRequest.get().map(response => Ok(views.html.weather(response.json)))
}

所以基本上,json只有在future完成时才可用,所以你只能将它传递给map函数内的视图,还要注意我使用了Action.async这会创建一个期望一个动作Future[WsResponse] 而不仅仅是 WsResponse

还请记住,Futures 已被记忆,因此如果您将对它的引用存储在 val 中,它只会执行一次

编辑:修复了存储在 val 中的未来以避免记忆问题

【讨论】:

  • Futurememoised 是什么意思?虽然我明白你想说什么,但它仍然具有很大的误导性。
  • 我的意思是Future会缓存结果,所以对外部服务的调用只会发生一次。记忆是正确的术语,不知道为什么你会发现它具有误导性......
  • Future 代表一个value,它可能还没有被计算过。它与计算本身没有“直接”关系(这也反映在 Future API 中,您将看不到任何与计算本身交互的方式)。因此,根据定义 - 没有记忆。
  • 我不知道您为什么首先决定将您的futureResponse 声明为val。当这是开发人员想要的时,很难想出一个真实世界的场景。
  • 我不同意,Future 直接链接到计算,当你构造未来时传递给它,计算它立即开始,除非你创建它永远不会再次执行一个新的,这使得 Future 非引用透明,这就是为什么你有像 scalaz Task 这样的替代品......
【解决方案2】:

这是无法访问的,因为您必须使用回调方法来访问/传递 Future 中的内容。这就是 println(response.json)map 回调中显示您感兴趣的数据/内容的原因。

您可以参考Accessing value returned by scala futures

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-02-03
    • 2011-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-16
    • 2019-11-01
    相关资源
    最近更新 更多