swift - 如果需要异步结果,请快速等待
问题描述
我正在学习如何使用完成处理程序和调度。有一个带有两个可选参数(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)
}
推荐阅读
- asp.net - vb.net 如何在列表框中显示数据库值?
- jqassistant - 通过命令行使用 jQAssistant-Maven-Plugin 时传递参数“ruleParameters”
- api - 找不到数据源:org.apache.dsext.spark.datasource.rest.RestDataSource
- data-visualization - How to make a dynamic tableau x-axis that gets changed when a different dimension is selected as a filter?
- algorithm - 从堆中弹出所有 n 个元素的复杂性是多少?
- spring-boot - Helm,在 values.yaml 中评估 linux 环境变量
- java - Java对新数组中的索引进行排序
- npm - 我的 webpack babel 加载器没有编译我的 javascript 代码
- jsonschema - 如何验证包含 MIXED 类型对象的 json 模式数组?
- regex - 正则表达式替换 - 删除不匹配的值