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

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

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

繼續您的 Swift 并發之旅

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

結論

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

轉自 Async let explained: call async functions in parallel

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,622評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,716評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,746評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,991評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,706評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,036評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,029評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,203評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,725評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,451評論 3 361
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,677評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,161評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,857評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,266評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,606評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,407評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,643評論 2 380

推薦閱讀更多精彩內容