Swift - 异步/等待不停止让任务完成

发布于 2025-01-09 23:25:54 字数 926 浏览 5 评论 0原文

我正在编写一个简单的程序,旨在与服务器通信,获取一些信息并显示它。但是,我遇到了异步代码的问题,主要是代码没有停止以允许服务器在继续之前做出响应。

我知道我一定做错了什么,但不知道是什么,非常感谢任何帮助。

override func viewDidLoad() {
    super.viewDidLoad()
    Task{
        let accessToken = await getToken()
    }
    print("Done")
}

private func getToken() async -> String{
    let url = URL(string: "https://api.petfinder.com/v2/oauth2/token")
    let payload = "grant_type=client_credentials&client_id=GUQj1MdQN3QunoxXz4vdd0DHPlcJC6yuqCLCEXavriJ4W6wTYV&client_secret=7whgSG3ZX6m9Cwfr2vEakOH90fSn3g0isIlae0CC".data(using: .utf8)
    var request = URLRequest(url: url!)
    request.httpMethod = "POST"
    request.httpBody = payload

    do{
        let (data,_) = try await URLSession.shared.data(for: request)
        let APItoken: token = try! JSONDecoder().decode(token.self, from: data)
        return APItoken.access_token
    }
    catch{
        return ""
    }
}

I'm writing a simple program designed to talk to a server, get some information, and display it. However, I'm running into issues with the async code, mainly that the code isn't stopping to allow the server to respond before continuing.

I know I have to be doing something wrong but have no idea what, any help is appreciated.

override func viewDidLoad() {
    super.viewDidLoad()
    Task{
        let accessToken = await getToken()
    }
    print("Done")
}

private func getToken() async -> String{
    let url = URL(string: "https://api.petfinder.com/v2/oauth2/token")
    let payload = "grant_type=client_credentials&client_id=GUQj1MdQN3QunoxXz4vdd0DHPlcJC6yuqCLCEXavriJ4W6wTYV&client_secret=7whgSG3ZX6m9Cwfr2vEakOH90fSn3g0isIlae0CC".data(using: .utf8)
    var request = URLRequest(url: url!)
    request.httpMethod = "POST"
    request.httpBody = payload

    do{
        let (data,_) = try await URLSession.shared.data(for: request)
        let APItoken: token = try! JSONDecoder().decode(token.self, from: data)
        return APItoken.access_token
    }
    catch{
        return ""
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

初与友歌 2025-01-16 23:25:55

如果我理解这个问题,您会看到在 getToken() 方法完成之前打印“Done”,对吧?

问题是 print("Done") 位于 Task 之外。

当您调用 Task 时,它开始运行闭包中的内容,并在闭包后立即恢复,同时您的任务并行运行,而不会阻塞主线程。

print() 放在 Task 闭包中,就在 getToken() 方法之后,您会看到它是“完成 POST 请求后”。

    Task{
        let accessToken = await getToken()
        print("Done")
    }

If I understood the problem, you see "Done" being printed before the getToken() method is completed, right?

The problem is that print("Done") is outside of the Task.

When you call Task, it starts running what's in the closure and it immediately resumes after the closure, while your task is running in parallel, without blocking the main thread.

Place your print() inside the Task closure, right after the getToken() method, and you'll see that it'll be "Done" after you complete your POST request.

    Task{
        let accessToken = await getToken()
        print("Done")
    }
黑色毁心梦 2025-01-16 23:25:55

Await 不会完全阻塞您的代码,相反,进行调用的线程可用于执行其他操作,例如获取更多用户输入、执行其他正在等待结果且现在已获得结果的任务内容。就像闭包回调一样,await 之后的所有内容都将稍后执行,可能直到封闭任务为止。 Print(“done”) 不在您的任务中,因此不需要等待任务中的代码执行,任务内容可能在另一个线程中执行,因为它不包含必须在主线程中执行的代码线。

Await does not completely block your code, instead the thread that makes the call can be used to do something else, like get more user input, execute other task content that was waiting for a result and now has it. think like closure call backs, everything after the await, will be executed later, probable up to the enclosing task. Print(“done”) is not in your task, so it’s not required to wait for the code in the task execute, the task content is probable executing in another thread, as it doesn’t contain code that has to execute in the main thread.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文