我正在学习如何使用完成处理程序和调度。有一个带有两个可选参数(groupName
和groupId
)的函数。如果给出了groupName
,则必须使用该名称来检索groupId
。
这是我尝试等待的方法,以便在继续操作之前需要完成该方法,但是信号量只是无限期地等待。
func getTaskId(uid: String, groupName: String?, groupId: String?, taskName: String, handler: @escaping (Array<String>?, Error?) -> Void) {
var id: String? // this is groupId not task id *
let semaphore = DispatchSemaphore(value: 0)
if let groupName = groupName {
getGroupId(uid: uid, groupName: groupName) {(groupId, groupIdErr) in
if let err = groupIdErr {
handler(nil, err)
return
} else {
id = groupId!
semaphore.signal()
}
}
} else if let unwrappedId = groupId {
id = unwrappedId
semaphore.signal()
} else {
let err = xErrors.getTaskIdErr(message: "Failed to get group id")
handler(nil, err)
return
}
semaphore.wait()
guard let finalId = id else {return} // groupId will be used now
// use groupId to continue and get taskId...
}
做这样的事情的正确方法是什么?等待另一种方法的结果,但只需要if
即可。
答案 0 :(得分:0)
您正试图强制异步任务变得同步。不要那样做。
减少该函数以仅检索ID。
Fix
调用它,并在完成处理程序中处理ID
func getTaskId(uid: String, groupName: String?, groupId: String?, completion: @escaping (Result<String,Error>) -> Void) {
if let groupName = groupName {
getGroupId(uid: uid, groupName: groupName) { groupId, groupIdErr in
if let err = groupIdErr {
completion(.failure(err))
} else {
completion(.success(groupId))
}
}
} else if let unwrappedId = groupId {
completion(.success(unwrappedId))
} else {
let err = xErrors.getTaskIdErr(message: "Failed to get group id")
completion(.failure(err))
}
}
另一种方法是声明一个函数
getTaskId(uid: "1", groupName: "foo", groupId: nil) { result in
switch result {
case .success(let groupId):
// do something with groupId...
case .failure(let error): print(error)
}
}
然后将func doSomething(with groupId : String) {}
更改为
getTaskId
并使用它
func getTaskId(uid: String, groupName: String, completion: @escaping (Result<String,Error>) -> Void) {
getGroupId(uid: uid, groupName: groupName) { groupId, groupIdErr in
if let err = groupIdErr {
completion(.failure(err))
} else {
completion(.success(groupId))
}
}
}