一、引言
在Swift5.5引入了受結構化編程思維影響的結構化併發的併發編程方式。
以下是一個使用傳統的回調通知來實現的異步編程實例
在此種編程模式下,具有以下一些劣勢:
- 不能使用錯誤處理
- 不能使用for循環來處理所有的圖片
- 不容易理解等
以下是使用新的結構化併發編程的方式來還原原來的功能。
注意
關於此基於結構化併發的新的實現方式中設計到的async、await等關鍵字,如果讀者不理解的話,建議參與本作者其他的WWDC21文章。
可以看出此函數與上面的實現方式相比具有較大的進步
- 可以拋出錯誤
- 具有返回值
- 沒有使用遞歸
- 代碼更容易理解
雖然基於結構化併發的代碼比傳統的代碼要好很多,但是,還開更好!目前的代碼中下載縮略圖是串行進行的——下載一個圖片、生成一個縮略圖,這無法充分利用多核設備的能力。可以使用Swift5.5中的Task(任務)來進一步增強代碼的能力。 - 任務提供了一個併發執行代碼的上下文
- Swift編譯器對代碼進行檢查,可以避免併發錯誤
- 任務必須被明確的創建(編譯器不會隱式創建任務)
二、任務詳解
2.1 Async-let 任務
這是一個普通的綁定,這個流程對於大部分裏瞭解Swift讀者都是比較熟悉的。
通過添加async關鍵字,則創建了一個Async-let任務,以下流程圖描述了此執行流程。
以下是一個Async-let任務的實例。
fetchOneThumbnail函數是一個父任務,兩個async-let語句創建了兩個子任務。父任務在子任務完成後才能完成;如果一個子任務拋出異常,另外一個子任務被標記爲取消的,但是其子任務還是會運行。任務如果被取消,則其所有的子任務也被取消。
2.2 組任務
使用withThrowingTaskGroup 函數來創建任務組,任務組能夠處理併發任務數量不確定的情況。添加到組內的子任務可以以任何順序執行。
注意
在上面的.group.async中對thumbnails[id]的賦值會引發問題(多線程的問題)