Swift 异步 let 带循环

Pyt*_*tan 15 asynchronous swift

我想并行获取数据。我找到了一个并行调用 API 的示例,但我想async let variables用循环存储。

异步让我们举个例子。但是,此示例未使用循环。

async let firstPhoto = downloadPhoto(named: photoNames[0])
async let secondPhoto = downloadPhoto(named: photoNames[1])
async let thirdPhoto = downloadPhoto(named: photoNames[2])

let photos = await [firstPhoto, secondPhoto, thirdPhoto]
show(photos)
Run Code Online (Sandbox Code Playgroud)

我想做如下的事情。

let items = photoNames.map({ photo in
    async let item = downloadPhoto(named: photo)
    return item
}) 
let photos = await items
show(photos)
Run Code Online (Sandbox Code Playgroud)

Rob*_*Rob 21

您可以使用任务组。请参阅《Swift 编程语言:并发》的任务和任务组部分部分(这似乎是您获取示例的地方)。

\n

一个可以用withTaskGroup(of:returning:body:)创建一个任务组来并行运行任务,但最后将所有结果整理在一起。

\n

例如,这里是一个创建子任务的示例,该子任务返回 \xe2\x80\x9cname\xe2\x80\x9d 和 \xe2\x80\x9dimage\xe2\x80\x9d 的元组,并且该组返回这些名称的组合字典字符串及其关联的图像值:

\n
func downloadImages(names: [String]) async -> [String: UIImage] {\n    await withTaskGroup(\n        of: (String, UIImage).self,\n        returning: [String: UIImage].self\n    ) { [self] group in\n        for name in names {\n            group.addTask { await (name, downloadPhoto(named: name)) }\n        }\n\n        var images: [String: UIImage] = [:]\n\n        for await result in group {\n            images[result.0] = result.1\n        }\n\n        return images\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

或者,更简洁地说:

\n
func downloadImages(names: [String]) async -> [String: UIImage] {\n    await withTaskGroup(\n        of: (String, UIImage).self,\n        returning: [String: UIImage].self\n    ) { [self] group in\n        for name in names {\n            group.addTask { await (name, downloadPhoto(named: name)) }\n        }\n\n        var images: [String: UIImage] = [:]\n\n        for await result in group {\n            images[result.0] = result.1\n        }\n\n        return images\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

它们并行运行:

\n

在此输入图像描述

\n

但您可以从结果字典中提取它们:

\n
func downloadImages(names: [String]) async -> [String: UIImage] {\n    await withTaskGroup(of: (String, UIImage).self) { [self] group in\n        for name in names {\n            group.addTask { await (name, downloadPhoto(named: name)) }\n        }\n\n        return await group.reduce(into: [:]) { $0[$1.0] = $1.1 }\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n
\n

或者,如果您想要一个按原始顺序排序的数组,只需从字典构建一个数组:

\n
let stooges = ["moe", "larry", "curly"]\nlet images = await downloadImages(names: stooges)\n\nimageView1.image = images["moe"]\nimageView2.image = images["larry"]\nimageView3.image = images["curly"]\n
Run Code Online (Sandbox Code Playgroud)\n