首页 文章

我该如何等待scala dispatch(0.11.0)http get请求完成?

提问于
浏览
1

我正在使用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失败(因为我只对成功感兴趣),并且我以经典方式处理超时异常 .

我想我可以像小麦一样提到它,留在未来,但我需要更多练习......

2 回答

  • -2

    TL;DR

    我可以为您提供在异步工作流程中工作的最佳建议是 Future 中的内容保留在 Future 中 .

    Answer

    问题是你不知道 Future 何时完成,所以如果你想使用异步进程,你将不得不以异步方式编写 . 您编写的代码永远不会在您创建的_908706上停止或阻塞,因此在创建 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
    }
    
  • 3

    我终于设法用期货写出我想要的东西:

    def loop(): Future[String] = {
        val future = http(req).option
        future flatMap ((x: Option[Response]) => x match {
            case Some(rep) => rep.getResponseBody
            case None => loop()
        }
    }
    

    现在我可以使用此函数的结果而无需明确地等待响应 .

相关问题