人们经常问“如何延迟功能或代码块?”是一个非常常见的问题。但这不是我所需要的。
我需要我的代码等待某个任务完成,否则我的函数会收到一个错误,提示我没有access_token(因为该代码不会等待从Spotify服务器获取数据)。
到目前为止,这是我的代码,尝试添加DispatchGroup
:
func getAccessToken() throws -> Spotify.JSONStandard {
var accessToken: Spotify.JSONStandard!
let group = DispatchGroup() // <- Create group
group.enter() // <- Enter group
Alamofire.request("https://accounts.spotify.com/api/token", method: .post, parameters: spotify.parameters, headers: nil).responseJSON(completionHandler: {
response in
// Check if response is valid
if let newValue = response.result.value as? Spotify.JSONStandard {
accessToken = newValue
}
group.leave() // <- Leave group
})
group.wait() // <- Wait until task is completed
// \/ Delay this code until complete \/
if accessToken != nil {
return accessToken
}
else {
throw SpotifyError.failedToGetAccessToken
}
// /\ /\
}
没有分组,我的代码将抛出SpotifyError.failedToGetAccessToken
(access_token为nil
)。
但是,添加组后,我的代码只是挂起并永远等待。如何延迟此代码的完成时间?
我知道获取令牌没有问题,就像我删除return
并在请求中放置打印内容一样,我得到了预期的结果。
如有任何疑问,请询问
答案 0 :(得分:3)
不要尝试使异步任务同步
这是一个带有完成处理程序和自定义枚举的解决方案
enum Result {
case success(Spotify.JSONStandard), failure(Error)
}
func getAccessToken(completion: @escaping (Result)->()) {
Alamofire.request("https://accounts.spotify.com/api/token", method: .post, parameters: spotify.parameters, headers: nil).responseJSON(completionHandler: {
response in
// Check if response is valid
if let newValue = response.result.value as? Spotify.JSONStandard {
completion(.success(newValue)
} else {
completion(.failure(SpotifyError.failedToGetAccessToken))
}
})
}
并调用它
getAccessToken { result in
switch result {
case .success(let token) : // do something with the token
case .failure(let error) : // do something with the error
}
}