如何连接 DispatchGroup 和 Executed Request Alamofire?
How connect DispatchGroup and Executed Request Alamofire?
我有一个简单的线程任务,但似乎对其他人都有帮助的东西对我不起作用,我不明白为什么。
这是我的按钮处理:
AnyButton(action: {
if isPhoneMode {
print("starting long running tasks")
let group = DispatchGroup()
group.enter()
DispatchQueue.global().async {
urlService.loginRequest(login: "+\(countryCode)\(phoneNumber)", password: password, completion: {
print("print in complition")
})
print("long task done!")
group.leave()
}
group.notify(queue: DispatchQueue.global()) {
print("all tasks done!")
}
}
这是loginRequest
:
func loginRequest(login: String, password: String, completion: @escaping () -> Void) {
let parameters: Parameters = [
"language": "EN",
"password": password,
"username": login
]
let url = "someURL"
let authRequest = AF.request(url,
method: .post,
parameters: parameters,
encoding: JSONEncoding.default)
authRequest.responseString { response in
switch response.result {
case .success(let value):
let responseArr = value.components(separatedBy: "\u{0022}")
if responseArr[11] == "ACTIVE" {
self.loginStatus = .correctLogin
print("correct login!")
}
case .failure(let error):
print("Error: \(String(describing: error))")
self.loginStatus = .requestFail
}
}
completion()
}
group.notify
无法正确跟踪我的请求。正确的登录始终在控制台中持续:为什么这样?
starting long running tasks
print in complition
long task done!
all tasks done!
correct login!
我希望它在“long task done”之前。我该怎么做?
首先你误用了DispatchGroup
。正如名称 group 暗示它用于多项任务,但您只执行一项任务。
意外行为的原因是leave
命令在完成闭包之外。所以leave
会被立即执行,群调用notify
如果没有 DispatchGroup
,这会达到您的预期
AnyButton(action: {
if isPhoneMode {
print("starting long running tasks") // actually one task
DispatchQueue.global().async {
urlService.loginRequest(login: "+\(countryCode)\(phoneNumber)", password: password, completion: {
DispatchQueue.main.async {
print("print in completion")
print("long task done!")
}
})
}
}
你问:
“Correct login” always last in console: Why so?
因为您对完成处理程序的调用不在正确的位置。例如
func loginRequest(login: String, password: String, completion: @escaping () -> Void) {
…
authRequest.responseString { response in
switch response.result { … }
completion() // Move `completion` here
}
// completion() // It should not be here
}
您的调度组中有类似的问题,即 leave
属于完成处理程序:
AnyButton(action: {
if isPhoneMode {
print("starting long running tasks")
let group = DispatchGroup()
group.enter()
urlService.loginRequest(login: "+\(countryCode)\(phoneNumber)", password: password) {
print("print in completion")
group.leave() // Move `leave` here
}
print("long task done!")
// group.leave() // not here
group.notify(queue: DispatchQueue.global()) {
print("all tasks done!")
}
}
})
注意,我已经删除了对全局队列的冗余调度(因为 loginRequest
已经异步运行)。
但是因为你只有一个任务,调度组也是多余的。仅当您有多个任务需要在完成时得到通知时才使用组。不过,在这种情况下,它是句法噪音。因此,这可以进一步简化为:
AnyButton(action: {
if isPhoneMode {
print("starting long running tasks")
urlService.loginRequest(login: "+\(countryCode)\(phoneNumber)", password: password) {
print("print in completion")
}
}
})
我有一个简单的线程任务,但似乎对其他人都有帮助的东西对我不起作用,我不明白为什么。
这是我的按钮处理:
AnyButton(action: {
if isPhoneMode {
print("starting long running tasks")
let group = DispatchGroup()
group.enter()
DispatchQueue.global().async {
urlService.loginRequest(login: "+\(countryCode)\(phoneNumber)", password: password, completion: {
print("print in complition")
})
print("long task done!")
group.leave()
}
group.notify(queue: DispatchQueue.global()) {
print("all tasks done!")
}
}
这是loginRequest
:
func loginRequest(login: String, password: String, completion: @escaping () -> Void) {
let parameters: Parameters = [
"language": "EN",
"password": password,
"username": login
]
let url = "someURL"
let authRequest = AF.request(url,
method: .post,
parameters: parameters,
encoding: JSONEncoding.default)
authRequest.responseString { response in
switch response.result {
case .success(let value):
let responseArr = value.components(separatedBy: "\u{0022}")
if responseArr[11] == "ACTIVE" {
self.loginStatus = .correctLogin
print("correct login!")
}
case .failure(let error):
print("Error: \(String(describing: error))")
self.loginStatus = .requestFail
}
}
completion()
}
group.notify
无法正确跟踪我的请求。正确的登录始终在控制台中持续:为什么这样?
starting long running tasks
print in complition
long task done!
all tasks done!
correct login!
我希望它在“long task done”之前。我该怎么做?
首先你误用了DispatchGroup
。正如名称 group 暗示它用于多项任务,但您只执行一项任务。
意外行为的原因是leave
命令在完成闭包之外。所以leave
会被立即执行,群调用notify
如果没有 DispatchGroup
AnyButton(action: {
if isPhoneMode {
print("starting long running tasks") // actually one task
DispatchQueue.global().async {
urlService.loginRequest(login: "+\(countryCode)\(phoneNumber)", password: password, completion: {
DispatchQueue.main.async {
print("print in completion")
print("long task done!")
}
})
}
}
你问:
“Correct login” always last in console: Why so?
因为您对完成处理程序的调用不在正确的位置。例如
func loginRequest(login: String, password: String, completion: @escaping () -> Void) {
…
authRequest.responseString { response in
switch response.result { … }
completion() // Move `completion` here
}
// completion() // It should not be here
}
您的调度组中有类似的问题,即 leave
属于完成处理程序:
AnyButton(action: {
if isPhoneMode {
print("starting long running tasks")
let group = DispatchGroup()
group.enter()
urlService.loginRequest(login: "+\(countryCode)\(phoneNumber)", password: password) {
print("print in completion")
group.leave() // Move `leave` here
}
print("long task done!")
// group.leave() // not here
group.notify(queue: DispatchQueue.global()) {
print("all tasks done!")
}
}
})
注意,我已经删除了对全局队列的冗余调度(因为 loginRequest
已经异步运行)。
但是因为你只有一个任务,调度组也是多余的。仅当您有多个任务需要在完成时得到通知时才使用组。不过,在这种情况下,它是句法噪音。因此,这可以进一步简化为:
AnyButton(action: {
if isPhoneMode {
print("starting long running tasks")
urlService.loginRequest(login: "+\(countryCode)\(phoneNumber)", password: password) {
print("print in completion")
}
}
})