Async let 是Swift并發(fā)框架的一部分,允許異步實(shí)例化一個(gè)常量。并發(fā)框架引入了async-await的概念,這使得異步方法的并發(fā)性結(jié)構(gòu)化,代碼更易讀。
如果你是第一次接觸async-await,建議先閱讀我的文章Swift 中的async/await ——代碼實(shí)例詳解。
如何使用 async let
在解釋如何使用 async let 時(shí),了解何時(shí)使用 async let 更為重要。我將向您介紹使用異步方法加載隨機(jī)圖像的代碼示例:
func loadImage(index: Int) async -> UIImage {
let imageURL = URL(string: "https://picsum.photos/200/300")!
let request = URLRequest(url: imageURL)
let (data, _) = try! await URLSession.shared.data(for: request, delegate: nil)
print("Finished loading image \(index)")
return UIImage(data: data)!
}
如果沒(méi)有 async let,我們將按如下方式調(diào)用此方法:
func loadImages() {
Task {
let firstImage = await loadImage(index: 1)
let secondImage = await loadImage(index: 2)
let thirdImage = await loadImage(index: 3)
let images = [firstImage, secondImage, thirdImage]
}
}
通過(guò)這種方式,我們告訴我們的應(yīng)用程序等待第一個(gè)圖像被返回,直到它可以繼續(xù)獲取第二個(gè)圖像。所有圖像都按順序加載,我們將永遠(yuǎn)在控制臺(tái)中看到以下順序打印出來(lái):
Finished loading image 1
Finished loading image 2
Finished loading image 3
起初,這可能看起來(lái)很好。我們的圖片是異步加載的,我們最終得到了一個(gè)圖片數(shù)組,我們可以用它來(lái)在視圖中顯示。然而,并行加載圖像,并從可用的系統(tǒng)資源中獲益,會(huì)有更高的性能。
這就是async let的用武之地:
func loadImages() {
Task {
async let firstImage = loadImage(index: 1)
async let secondImage = loadImage(index: 2)
async let thirdImage = loadImage(index: 3)
let images = await [firstImage, secondImage, thirdImage]
}
}
有幾個(gè)重要的部分需要指出:
- 我們的圖像數(shù)組現(xiàn)在需要使用
await關(guān)鍵字來(lái)定義,因?yàn)槲覀冋谔幚懋惒匠A?/li> - 一旦我們定義了
async let方法就會(huì)開(kāi)始執(zhí)行
最后一點(diǎn)基本上意味著,其中一張圖片在數(shù)組中被等待之前就已經(jīng)被你的應(yīng)用程序下載了。在這種情況下,這只是理論上的,因?yàn)槟愕拇a執(zhí)行的速度很可能比圖片的下載速度快。
運(yùn)行此代碼將在控制臺(tái)中顯示不同的輸出:
Finished loading image 3
Finished loading image 1
Finished loading image 2
每次你運(yùn)行應(yīng)用程序時(shí),它可能是不同的,因?yàn)轫樞蛉Q于下載圖像所需的請(qǐng)求時(shí)間。
什么時(shí)候使用 async let?
當(dāng)你在代碼的后期才需要異步方法的結(jié)果時(shí),應(yīng)該使用async let。如果你的代碼中的任何后續(xù)行都依賴于異步方法的結(jié)果,你應(yīng)該使用await來(lái)代替。
我可以在頂層聲明 async let 嗎?
您可能想知道以下代碼在 Swift 中是否有效:
final class ContentViewModel: ObservableObject {
async let firstImage = await loadImage(index: 1)
// .. rest of your code
}
不幸的是,編譯器會(huì)顯示錯(cuò)誤:

async let 不能在頂級(jí)聲明中使用。
換句話說(shuō),您只能在方法內(nèi)的本地聲明上使用 async let。
繼續(xù)您的 Swift 并發(fā)之旅
并發(fā)更改不僅僅是 async-await,還包括許多您可以在代碼中受益的新功能。所以當(dāng)你在做的時(shí)候,為什么不深入研究其他并發(fā)特性呢?
- Swift 中的 async/await
- Swift 中的 async let
- Swift 中的 Task
- Swift 中的 Actors 使用以如何及防止數(shù)據(jù)競(jìng)爭(zhēng)
- Swift 中的 MainActor 使用和主線程調(diào)度
- 理解 Swift Actor 隔離關(guān)鍵字:nonisolated 和 isolated
- Swift 中的 Sendable 和 @Sendable 閉包
- Swift 中的 AsyncThrowingStream 和 AsyncStream
- Swift 中的 AsyncSequence
結(jié)論
Async let 允許我們組合多個(gè)異步調(diào)用并一次等待所有結(jié)果。這是一種利用可用系統(tǒng)資源并行下載的好方法,同時(shí)在所有異步請(qǐng)求完成后仍然組合結(jié)果。結(jié)合 async-await 和 actor,它們形成了一種在 Swift 中處理并發(fā)的強(qiáng)大的新方法。
轉(zhuǎn)自 Async let explained: call async functions in parallel