Swift 中的 async let

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 can't be used at top level declarations

async let 不能在頂級(jí)聲明中使用。

換句話說(shuō),您只能在方法內(nèi)的本地聲明上使用 async let

繼續(xù)您的 Swift 并發(fā)之旅

并發(fā)更改不僅僅是 async-await,還包括許多您可以在代碼中受益的新功能。所以當(dāng)你在做的時(shí)候,為什么不深入研究其他并發(fā)特性呢?

結(jié)論

Async let 允許我們組合多個(gè)異步調(diào)用并一次等待所有結(jié)果。這是一種利用可用系統(tǒng)資源并行下載的好方法,同時(shí)在所有異步請(qǐng)求完成后仍然組合結(jié)果。結(jié)合 async-awaitactor,它們形成了一種在 Swift 中處理并發(fā)的強(qiáng)大的新方法。

轉(zhuǎn)自 Async let explained: call async functions in parallel

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容