我正在修改一些使用公共完成的旧代码,以便使用Parse的新的异步/等待语法。以下是一个例子:
static func get(
className: String,
id: String,
_ completion: @escaping (PFObject?) -> Void
) {
let query = PFQuery(className: className)
query.getObjectInBackground(withId: id) { object, _ in
completion(object)
}
}正在变成这样:
static func get(
className: String,
objectId: String
) async -> PFObject? {
let query = PFQuery(className: className)
return await withCheckedContinuation { continuation in
query.getObjectInBackground(withId: objectId) { result, _ in
continuation.resume(returning: result)
}
}
}但是,我以前也使用过DispatchQueue/QoS,因此旧的函数实际上如下所示:
static func get(
className: String,
id: String,
_ completion: @escaping (PFObject?) -> Void
) {
let query = PFQuery(className: className)
DispatchQueue.global(qos: .userInteractive).async {
query.getObjectInBackground(withId: id) { object, _ in
DispatchQueue.main.async {
completion(object)
}
}
}
}如何将它与异步/等待语法结合使用?有必要吗?
谢谢你的帮助
发布于 2022-07-08 19:28:15
您可能希望在Swift任务中执行异步函数get(className:objectId:),使用此任务初始化器
func foo(
className: String,
objectId: String
) async -> PFObject? {
await Task(priority: .userInitiated) {
await get(className: className, objectId: objectId)
}
.value
}注意,当使用此任务初始化器时,您将得到“结构化并发”,这意味着函数foo中的嵌入任务继承了调用函数的参与者上下文。也就是说,您可以安全地使用任何线程调用的结果。
这也意味着,如果运行函数foo()的任务被取消,嵌入的任务也将被取消。当然,取消是合作的,这意味着您需要显式地停止正在运行的任务。例如,在用例中首选的方法是使用withTaskCancellationHandler,它在PFQuery对象上调用cancel()。或者,当您有一个长时间运行的迭代任务时,您可以在任务进行期间以合理的步骤轮询该任务的取消状态。
还请阅读有关“分离”的内容,它们在取消和继承任务优先级方面的行为有所不同。
关于是否需要它的问题:我假设,您会问是否需要使用指定优先级:简短的回答:在许多用例中,只从函数的任何线程继承优先级可能更安全。
在您的情况下,我不会显式地更改它:当从低优先级的后台线程调用它时,您的任务也应该继承此优先级。没有理由在userInitiated中使它具有高度的优先级。否则,如果您的函数已经从用户操作中调用,它也将继承这个更高的优先级。我相信,这是大多数用例所需要的。
而且,当您的工作人员在后台线程中运行时,就像代码中的情况一样,这个任务“安排得多快”并不重要。
因此,基本上您最终得到了定义的异步get函数,按原样使用,一切都很好。;)
https://stackoverflow.com/questions/72910872
复制相似问题