【发布时间】:2020-08-27 18:07:32
【问题描述】:
如何在 while 循环中使用完成处理程序/调度队列?
我有一个名为getHub() 的方法,它是一个完成处理程序,因为我希望在完成相关值后执行代码。当用户按下按钮时,我调用它:
SetupAPI().getHub(completion: { response, error in
print("testing")
print(response)
print(error)
})
(上面的代码是下面所有代码应该结束的地方)
它调用我的 API,如果 API 返回一个错误/我没有预料到的值,或者如果 Almofire 由于某种原因无法执行请求,那么它会将一个添加到 tries 变量中。允许的最大尝试次数为 3,由 maxTries 变量给出。如果tries 变量等于maxTries 变量,则布尔型timeout 设置为true。如果tries 变量低于maxTries 变量,则代码将等待timeoutInSeconds - 这是10 秒 - 退出while 循环之前的时间量,这应该再次运行代码。
同样,如果从我的 API 获取数据返回正确的值,则布尔值 found 设置为 true。
如果这些变量中的任何一个为真,那么 while 循环就会中断。并且错误被发送回上述代码的完成处理程序(然后我可以告诉用户出现了问题)。
但是,当我运行它时,上面的完成处理程序并没有完成,代码只是通过 while 循环并一遍又一遍地调用函数,因为我的控制台通过我的两个打印填充了 starting 和 fetching下面代码中的调试语句。有什么问题,我可以在这种情况下使用 DispatchQueue/完成处理程序吗?
通过上述代码调用的函数:
func getHub(completion: @escaping (Bool, Error?) -> Void) {
var tries = 0
let maxTries = 3
let timeoutInSeconds = 10.0
var found = false
var timeout = false
while !found || !timeout{
print("starting")
getHubCallAPI(completion: {status, error in
if(error == nil){
print(status)
if (status == "No documents found"){
if(tries >= maxTries){
print("Tired too many times")
timeout = true
return completion(false, nil)
}
tries += 1
DispatchQueue.main.asyncAfter(deadline: .now() + timeoutInSeconds){
return
}
}else{
found = true
print("Hub found")
return completion(true, nil)
}
}else{
print("error")
return completion(false, error)
}
})
}
}
调用API并将其返回给上面的函数的函数^^:
func getHubCallAPI(completion: @escaping (String, Error?) -> Void) {
print("fetching")
AF.request("https://discovery.ellisn.com", encoding: URLEncoding.default).response { response in
print("Request: \(response.request)")
print("Response: \(response.response)")
print("Error: \(response.error)")
if(response.error != nil){
return completion("", response.error)
}
if let data = response.data, let status = String(data: data, encoding: .utf8) {
return completion(status, nil)
}
}
}
如有任何问题或需要更多说明,请直接提问。谢谢。
【问题讨论】:
-
这是因为您的 while 循环在主线程上运行,并且不会等待 getHubCallAPI(在另一个线程上)完成。您可以调用一次 getHubCallAPI,然后在完成时递归调用它(直到
found或timeout)。 -
@pawello2222 您能否将您的评论添加为我自己和其他人的代码的答案以改进这个问题?
-
我将其添加为答案。如果我在完成处理程序中误解了您想要的行为,请随时纠正我。
标签: swift while-loop alamofire completionhandler