Swift 中的 async let

Async let 是Swift併發框架的一部分,允許異步實例化一個常量。併發框架引入了async-await的概念,這使得異步方法的併發性結構化,代碼更易讀。

如果你是第一次接觸async-await,建議先閱讀我的文章Swift 中的async/await ——代碼實例詳解

如何使用 async let

在解釋如何使用 async let 時,瞭解何時使用 async let 更爲重要。我將向您介紹使用異步方法加載隨機圖像的代碼示例:

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)!
}

如果沒有 async let,我們將按如下方式調用此方法:

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]
    }
}

通過這種方式,我們告訴我們的應用程序等待第一個圖像被返回,直到它可以繼續獲取第二個圖像。所有圖像都按順序加載,我們將永遠在控制檯中看到以下順序打印出來:

Finished loading image 1
Finished loading image 2
Finished loading image 3

起初,這可能看起來很好。我們的圖片是異步加載的,我們最終得到了一個圖片數組,我們可以用它來在視圖中顯示。然而,並行加載圖像,並從可用的系統資源中獲益,會有更高的性能。

這就是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]
    }
}

有幾個重要的部分需要指出:

  • 我們的圖像數組現在需要使用 await 關鍵字來定義,因爲我們正在處理異步常量
  • 一旦我們定義了 async let 方法就會開始執行

最後一點基本上意味着,其中一張圖片在數組中被等待之前就已經被你的應用程序下載了。在這種情況下,這只是理論上的,因爲你的代碼執行的速度很可能比圖片的下載速度快。

運行此代碼將在控制檯中顯示不同的輸出:

Finished loading image 3
Finished loading image 1
Finished loading image 2

每次你運行應用程序時,它可能是不同的,因爲順序取決於下載圖像所需的請求時間。

什麼時候使用 async let?

當你在代碼的後期才需要異步方法的結果時,應該使用async let。如果你的代碼中的任何後續行都依賴於異步方法的結果,你應該使用await來代替。

我可以在頂層聲明 async let 嗎?

您可能想知道以下代碼在 Swift 中是否有效:

final class ContentViewModel: ObservableObject {
    
    async let firstImage = await loadImage(index: 1)

    // .. rest of your code
}

不幸的是,編譯器會顯示錯誤:

async let 不能在頂級聲明中使用。

換句話說,您只能在方法內的本地聲明上使用 async let

繼續您的 Swift 併發之旅

併發更改不僅僅是 async-await,還包括許多您可以在代碼中受益的新功能。所以當你在做的時候,爲什麼不深入研究其他併發特性呢?

結論

Async let 允許我們組合多個異步調用並一次等待所有結果。這是一種利用可用系統資源並行下載的好方法,同時在所有異步請求完成後仍然組合結果。結合 async-awaitactor,它們形成了一種在 Swift 中處理併發的強大的新方法。

轉自 Async let explained: call async functions in parallel

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章