Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/83.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 什么';发送一个简单的HTTP请求并用Akka获得响应的最佳实践是什么?_Scala_Akka_Akka Http - Fatal编程技术网

Scala 什么';发送一个简单的HTTP请求并用Akka获得响应的最佳实践是什么?

Scala 什么';发送一个简单的HTTP请求并用Akka获得响应的最佳实践是什么?,scala,akka,akka-http,Scala,Akka,Akka Http,我试着这样编写代码: val requestUri : Uri = baseUri.withQuery(Uri.Query("aid" -> av))//av is a query parameter val responseFuture: Future[HttpResponse] = Http(system).singleRequest(HttpRequest(GET, uri = requestUri)) val response = Await.result(responseFutu

我试着这样编写代码:

val requestUri : Uri = baseUri.withQuery(Uri.Query("aid" -> av))//av is a query parameter
val responseFuture: Future[HttpResponse] =
Http(system).singleRequest(HttpRequest(GET, uri = requestUri))
val response = Await.result(responseFuture, Duration.Inf)

我想我得到了正确的回答,但是我怎样才能得到回答的内容呢?这样做的最佳实践是什么?像这样使用
Future
正确吗?

一般来说,在
Future
上使用
wait
是不好的形式。这通常是不必要的,但如果你对未来不熟悉,“感觉”是正确的方法

一旦结果成为未来,您可以将计算留在未来的“内部”,并在原始值的基础上添加更多功能

直接处理你的问题,你可以使用未来的操作符,而不是等待“得到响应的内容”(参见Frederic A.的答案,为什么要在下一个解决方案之前考虑流):< /P> 这一系列操作也可以通过以下方式完成:

val responseBody : Future[ByteString] = 
  for {
    entity <- responseFuture.entity
    strict <- entity.toStrict(10 seconds)
    body   <- strict.data
  } yield body
再次请注意,我们能够通过testring将
HttpResponse
转换为
HttpResponse
,并在不使用wait的情况下打印结果。相反,我们使用
map
flatMap
foreach
来完成任务


我第一次使用Futures时使用的一个心理技巧是将未来想象成一种特殊的数组。您不能从数组中选择元素,Wait就是这样做的,但是当您想要对元素进行操作时,您可以在特殊数组中使用map和flatMap。

一般来说,在
将来的
上使用
Wait
是不好的。这通常是不必要的,但如果你对未来不熟悉,“感觉”是正确的方法

一旦结果成为未来,您可以将计算留在未来的“内部”,并在原始值的基础上添加更多功能

直接处理你的问题,你可以使用未来的操作符,而不是等待“得到响应的内容”(参见Frederic A.的答案,为什么要在下一个解决方案之前考虑流):< /P> 这一系列操作也可以通过以下方式完成:

val responseBody : Future[ByteString] = 
  for {
    entity <- responseFuture.entity
    strict <- entity.toStrict(10 seconds)
    body   <- strict.data
  } yield body
再次请注意,我们能够通过testring将
HttpResponse
转换为
HttpResponse
,并在不使用wait的情况下打印结果。相反,我们使用
map
flatMap
foreach
来完成任务


我第一次使用Futures时使用的一个心理技巧是将未来想象成一种特殊的数组。您不能从数组中选择元素,这正是Wait所做的,但您可以在需要对元素进行操作时在特殊数组中使用map和flatMap。

Akka http基于Akka streams,原因很多,可以帮助您理解这里发生了什么:如果运行代码的计算机只有64Gb的RAM,而HTTP响应的大小是784Tb,也就是说,远远超过RAM+交换的容量,该怎么办?流式解决方案是解决这一问题的唯一方法,而这正是akka http擅长的

因此,在您的例子中,当
responseFuture
完成时,基本上意味着只有http响应的头可用,而不是内容可用。请记住,内容可能很大,下载需要几个小时,但您仍然可以期望
响应未来
在不到一秒钟内完成

您所称的响应内容称为http实体。Akka http将其作为流提供,但对于像您这样的情况,您可以调用实体上的
.toStrict
,将其作为字节数组(未来的)而不是流


最后,使用
wait
几乎永远都不对。你应该在未来完成时采取行动,或者使用
.onComplete
/
。onSuccess
/
。onFailure
,或者将结果映射到某个东西,可能使用
。map
和/或
与其他期货结合使用。flatMap
Akka http基于很多原因基于Akka流,可以帮助您理解这里发生了什么:如果运行代码的计算机只有64Gb的RAM,而HTTP响应的大小是784Tb,也就是说,远远超过RAM+交换的容量,该怎么办?流式解决方案是解决这一问题的唯一方法,而这正是akka http擅长的

因此,在您的例子中,当
responseFuture
完成时,基本上意味着只有http响应的头可用,而不是内容可用。请记住,内容可能很大,下载需要几个小时,但您仍然可以期望
响应未来
在不到一秒钟内完成

您所称的响应内容称为http实体。Akka http将其作为流提供,但对于像您这样的情况,您可以调用实体上的
.toStrict
,将其作为字节数组(未来的)而不是流


最后,使用
wait
几乎永远都不对。你应该在未来完成时采取行动,或者使用
.onComplete
/
.onSuccess
/
.onFailure
或者将结果映射到某个东西,可能使用
.map
和/或
.flatMap
与其他未来结合使用。谢谢你的帮助!但是代码中有一个小错误:
toStrict
只接受
FiniteDuration
作为参数,因此
Duration.Inf
将导致类型不匹配。将其更改为
1秒
并导入
import scala.concurrent.duration.\u
将修复它。我还有一个问题:设置超时的最佳做法是什么?@HuangYuheng欢迎您。我在有限的时间内修改了答案。一般来说,没有超时的“最佳实践”。我通常拍摄一段时间,99.9%的时间会检索到身体,这取决于您查询的服务。祝你黑客愉快。谢谢你的帮助!但是有一个
responseBody foreach { body =>
  println s"body: ${body.utf8String}"
}