我观看了在Swift中探索结构化并发
视频以及其他相关的视频/文章/书籍(来自Sundell的Swift,Hacking with Swift,Ray Renderlich),但那里的所有示例都非常琐碎 - 异步函数通常只有一个异步调用。在实际代码中应该如何处理?
例如:
...
task = Task {
var longRunningWorker: LongRunningWorker? = nil
do {
var fileURL = state.fileURL
if state.needsCompression {
longRunningWorker = LongRunningWorker(inputURL: fileURL)
fileURL = try await longRunningWorker!.doAsyncWork()
}
let urls = try await ApiService.i.fetchUploadUrls()
if let image = state.image, let imageData = image.jpegData(compressionQuality: 0.8) {
guard let imageUrl = urls.signedImageUrl else {
fatalError("Cover art supplied but art upload URL is nil")
}
try await ApiService.i.uploadData(url: imageUrl, data: imageData)
}
let fileData = try Data(contentsOf: state.fileUrl)
try await ApiService.i.uploadData(url: urls.signedFileUrl, data: fileData)
try await ApiService.i.doAnotherAsyncNetworkCall()
} catch {
longRunningWorker?.deleteFilesIfNecessary()
throw error
}
}
...
在某个时候,我将调用 task.cancel()
。
是谁负责取消什么?到目前为止,我看到的示例都会使用 try Task.checkCancellation()
,但对于这段代码来说,那行代码应该每隔几行出现一次 - 是这样做吗?
如果API服务使用URLSession,则在iOS 15上调用将被取消,但我们不使用URLSession代码的异步变体,因此必须手动取消调用。此外,所有长时间运行的工作程序代码也适用于此。
我还在考虑是否可以在每个异步函数中添加此检查,但是这样基本上所有异步函数都将具有相同的模板代码,这似乎是错误的,并且我没有在任何视频中看到过这种做法。
编辑:已删除回调调用,因为它们与问题无关。
checkCancellation()
,则模态只会在当前网络调用结束后关闭。取消处理程序会立即触发,但不知道是否有一种方法可以通过抛出错误立即停止父任务执行。 - Raimundas Sakalauskas