我正在使用 scala dispatch (0.11.0) 库向远程服务器发送 HTTP GET 请求。我想在执行请求后的代码之前等待响应。
我的请求是这样的:
val req = :/("myurl.com") <:< myheaders OK as.Response(identity)
如果我写:
val future = http(req)
future()
var res: String = null
future onComplete {
case Success(r) => res = r.getResponseBody
case _ => println("KO")
}
println(res)
我得到空值。 如果我这样写也是这样:
val future = http(req)
var res: String = null
while (!future.isCompleted) {
Thread.sleep(1000)
}
future onComplete {
case Success(r) => res = r.getResponseBody
case _ => println("KO")
}
println(res)
但是使用下面的代码:
val future = http(req)
var res: String = null
future onComplete {
case Success(r) => res = r.getResponseBody
case _ => println("KO")
}
while (!future.isCompleted) {
Thread.sleep(1000)
}
println(res)
我得到了预期的响应。
有人明白吗? 在我看来,调用 Thread.sleep 并不是一件好事,有人可以给我一些提示,告诉我应该如何正确处理这个问题吗?
编辑:@Randal Schulz 感谢您的帮助,但正如您在评论中发表的那样,我无法验证您的回答。
因为我的问题是等待(并且什么都不做)直到我得到对 HTTP GET 请求的有效响应,我认为一个令人满意的方法是使用 Await.result。我从我的代码中删除了副作用。我使用选项方法来处理 Future 失败(因为我只对成功感兴趣),并且我以经典方式处理超时异常。
我想我可以像 wheaties 提到的那样,留在 Future,但我需要更多练习......
最佳答案
长话短说
对于在异步工作流中工作,我能给你的最好建议是进入 Future
的内容保留在 Future
中。
回答
问题是您不知道 Future
何时完成,因此如果您想使用异步过程,您将不得不以异步方式编写。您编写的代码永远不会在您创建的 Future
上停止或阻塞,因此在它创建 Future
并将其交给另一个线程的那一刻,当前线程就可以自由地执行然后计算 res
变量。
因此,将您正在做的大部分工作放在一个流程中,如下所示:
myFuture map (func1) map (func2) map (func3) onComplete{
case Success(value) => println(value.getResponseBody)
case _ => println('KO')
}
不要像现在这样尝试通过副作用访问某些东西。
如果你真的很聪明并且你有多个 Future
你可以组合它们:
val f1 = myFuture map(func1)
val f2 = myOtherFuture map(func2) map (func3)
val f3 = for{
v1 <- f1
v2 <- f2
} yield functionTakingBoth(v1, v2)
f3 onComplete{
//and do stuff here
}
关于scala - 我应该如何等待 scala dispatch (0.11.0) http get 请求完成?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21459904/