Swift 如果需要异步结果则等待
Swift wait if required for asynchronous result
我正在学习如何使用完成处理程序和分派。有一个带有两个可选参数(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
即可。
您正试图将异步任务强制变为同步。不要那样做。
减少函数以仅检索 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))
}
}
调用它并在完成处理程序中处理 id
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))
}
}
}
并使用它
if let groupName = groupName {
getTaskId(uid: "1", groupName: groupName) { result in
switch result {
case .success(let groupId):
doSomething(with : groupId)
case .failure(let error): print(error)
}
} else if groupId = groupId {
doSomething(with : groupId)
}
我正在学习如何使用完成处理程序和分派。有一个带有两个可选参数(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
即可。
您正试图将异步任务强制变为同步。不要那样做。
减少函数以仅检索 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))
}
}
调用它并在完成处理程序中处理 id
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))
}
}
}
并使用它
if let groupName = groupName {
getTaskId(uid: "1", groupName: groupName) { result in
switch result {
case .success(let groupId):
doSomething(with : groupId)
case .failure(let error): print(error)
}
} else if groupId = groupId {
doSomething(with : groupId)
}