我们如何等待HTTP请求完成? [英] How can we wait for HTTP requests to finish?

查看:271
本文介绍了我们如何等待HTTP请求完成?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在SO上使用了几个答案,我们设法编写并执行了一个基本的HTTP请求:

Using several answers on SO, we have managed to write and execute a basic HTTP request:

import Foundation

let url:URL = URL(string: "http://jsonplaceholder.typicode.com/posts")!
let session = URLSession.shared

var request = URLRequest(url: url)
request.httpMethod = "POST"
let paramString = "data=Hello"
request.httpBody = paramString.data(using: String.Encoding.utf8)

let task = session.dataTask(with: request as URLRequest) {
    (data, response, error) in

    guard let data = data, let _:URLResponse = response, error == nil else {
        print("error")
        return
    }

    let dataString: String =  String(data: data, encoding: String.Encoding.utf8)!
    print("here")

    print("Data: \(dataString)")
    print("Response: \(response!)")
}

task.resume()
while task.response == nil {}
print("Done")

你会注意到我们已经忙 - 等到设置了 task.response 。但是,既不会打印数据也不会打印响应,只有这里

You'll note that we already busy-wait until task.response is set. However, neither data nor response are printed, only here.

经过无休止的尝试,以这种或那种方式包装东西我们在这里确定我们有一个Heisenbug:代码中没有任何改变,有时这里被打印,有时什么也没有,而且非常非常非常 dataString (更不用说回复)。

After endless trials with wrapping things this or that way we determine that we have a Heisenbug here: changing nothing in the code, sometimes here is printed, sometimes nothing, and very, very rarely dataString (let alone response).

所以我们插入 sleep( 3)打印(完成)之前,奇迹奇迹,我们得到所有打印。

So we insert sleep(3) before print("Done") and, wonder of wonders, we get all prints.

然后我们大喊一声(我可能实际上已经抛出了一些东西),简单地想一想放弃Swift,但后来平静下来,像sirs一样面对并发布在这里。

Then we yelled a little bit (I may actually have thrown something), thought briefly about abandoning Swift altogether, but then calmed down enough to facepalm like sirs and post here.

显然,主线程终止是否有任何异步任务(线程?)仍在运行,从而终止所有的spawn。我们如何防止这种情况发生,即加入线程?

Apparently, the main thread terminates whether or not any asynchronous tasks (threads?) are still running or not, killing all its spawn. How can we prevent that from happening, that is "join" the threads?

奖金问题: Alamofire是否在幕后处理这个问题?

Bonus question: Does Alamofire deal with this behind the covers?

推荐答案

积极等待似乎是GCD的唯一途径。使用标准库材料,这是有效的:

Active waiting seems to be the only way on the GCD. Using standard library material, this is what works:

import Foundation

<...>

var done = false

let task = session.dataTask(with: request as URLRequest) {
    (data, response, error) in

    <...>
    done = true
}

task.resume()

repeat {
    RunLoop.current.run(until: Date(timeIntervalSinceNow: 0.1))
} while !done

这篇关于我们如何等待HTTP请求完成?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆