1. 前言
- 闭包形式的异步代码并不是structured
- 调用async函数并不会创建一个task,task只能通过显式声明来创建
2. Async-let Tasks
try-await取值方式,会阻塞当前线程。当取值完成之后才会赋值给变量并恢复线程
let (data, response) = try await URLSession.shared.data(for: request) <!--0-->
Async-let相当于把操作交给子任务去处理
- 只有所有的子任务都处理玩了,父任务才算处理完成
- 若一个任务有两个子任务,其中一个子任务抛出了一个error,这时父任务会把另外那个子任务标记为cancellation,表示他的结果已经不需要了,这个子任务会自己在恰当的时机终止运行。
cancellation checking
若一个任务有多个子任务,需要对子任务是否被取消进行检查
func fetchThumbnails(for ids: [String]) async throws -> [String: UIImage] { var thumbnails: [String: UIImage] = [:] for id in ids { try Task.checkCancellation() // 检查当前任务是否被取消 thumbnails[id] = try await fetchOneThumbnail(withID: id) } return thumbnails } <!--1-->
group中的操作会并行无序执行
@Sendable
:生成task的闭包。sendable闭包不能捕获mutable变量。只能捕获值类型、actors、实现了synchronization的类
4. Unstructured Tasks
会中断UnstructuredTask所在的task,仍然继承父task的优先级、actors、变量。但是需要手动管理
在非async函数中调用async函数:
async { }
func collectionView(_ view: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt item: IndexPath) { let ids = getThumbnailIDs(for: item) thumbnailTasks[item] = async { // 新建一个task defer { thumbnailTasks[item] = nil } let thumbnails = await fetchThumbnails(for: ids) display(thumbnails, in: cell) } } <!--2-->