我刚刚更新到 Xcode 13.2.1,现在可以访问异步等待,并且我正在尝试找到可以从合并“转换”为异步等待的地方。
我想实现以下目标...
给定一个像...的类型
struct Person {
let name: String
func fetchAvatar(completion: @escaping (UIImage?) -> Void) {
// fetch the image from the web and pass it into the completion.
}
}
Run Code Online (Sandbox Code Playgroud)
我目前有这样的功能......
func fetchAllTheAvatars(people: [Person], completion: ([UIImage]) -> Void) {
Publisher.MergeMany(
people.map { person in
Future<UIImage?, Never> { promise in
person.fetchAvatar { promise(.success($0)) }
}
}
)
.compactMap { $0 }
.collect()
.sink { completion($0) }
.store(in: &cancellables )
}
Run Code Online (Sandbox Code Playgroud)
现在......在我看来,这可能是转向使用 async wait 的一个很好的候选者,AsyncSequence也许......?!?但它不一定是理想的,我只是想了解如何使用它们。我习惯了async awaitJS 和 TS,这似乎有点不同。:D
我向我的 Person 添加了一个包装函数...
func fetchAvatar() async -> UIImage? {
await withCheckedContinuation { continuation in
fetchAvatar { image in
continuation.resume(returning: image)
}
}
}
Run Code Online (Sandbox Code Playgroud)
但现在我陷入了如何更新我的fetchAllTheAvatars功能的困境。
func fetchAllTheAvatars(people: [Person]) async -> [UIImage] {
people.map { ...???... }
}
Run Code Online (Sandbox Code Playgroud)
我在网上看到的所有地方似乎都在使用for await line in url.lines { ... },但我还没有 AsyncSequence。我需要以某种方式将我的非异步数组“转换”Person为AsyncSequenceof () -> Image?。
那可能吗?我的处理方式完全错误吗?
谢谢
Rob*_*Rob 11
标准模式是TaskGroup. 为各个图像添加任务,然后await循环添加for,map或者在本例中为reduce:
func fetchAllTheAvatars(people: [Person]) async -> [Person.ID: UIImage] {\n await withTaskGroup(of: (Person.ID, UIImage?).self) { group in\n for person in people {\n group.addTask { await (person.id, person.fetchAvatar()) }\n }\n \n return await group.reduce(into: [:]) { dictionary, result in \n if let image = result.1 {\n dictionary[result.0] = image\n }\n }\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n请注意,由于顺序无法保证,并且您的某些Person可能不会返回图像,因此我的实现返回一个高效的、与顺序无关的结构(即字典)。
不用说,上面假设您Person符合Identifiable:
struct Person: Identifiable {\n let id = UUID()\n let name: String\n \n func fetchAvatar() async -> UIImage? { \xe2\x80\xa6 }\n}\nRun Code Online (Sandbox Code Playgroud)\n