gpt4 book ai didi

swiftui - 如何在 SwiftUI 中使用 async/await 链接 AnyPublisher

转载 作者:行者123 更新时间:2023-12-05 05:39:43 24 4
gpt4 key购买 nike

链接 AnyPublisher 的典型方法是使用 Combine 运算符,例如 flatMap。


class MyService {
func getUserList() -> AnyPublisher<[User], Error> {
....
}

func getPostList(user: User) -> AnyPublisher<[Post], Error> {
...
}
}

class ViewModel: ObserableObject {
let service = MyService()

@published var post: [Post] = []

func fetchAllPostFromLastUser() {
service.getUserList().flatMap { [weak self] users in
if let user = users.last {
return self.service.getPosts(user: user)
} else {
return Fail(error:APIError.emptyUsers).eraseToAnyPublisher()
}
}
.sink { result in

}
}
}

有没有更优雅的方法来使用async/await,所以代码可以类似

class ViewModel: ObserableObject {
let service = MyService()

@published var post: [Post] = []

func fetchAllPostFromLastUser() {
let users = await service.getUserList().somethingMagicToConvertPublisherToAsync()
let posts = await service.getPostList(user: user.first).somethingMagicToConvertPublisherToAsync()
}
}

最佳答案

要使用 async/await,我们需要将 Publisher 转换为值的 AsyncStream,从而消除错误。

所以,有可能像(用 Xcode 13.4 测试过)

@MainActor class ViewModel: ObserableObject {
// ...

func collectPosts() async {
for await newUsers in service.getUserList().replaceError(with: []).values {
for user in newUsers {
for await newPost in service.getPost(user: user).replaceError(with: []).values {
post.append(contentsOf: newPost)
}
}
}
}

和用法类似

struct ContentView: View {
@StateObject var vm = ViewModel()

var body: some View {
YourViewHere()
.task {
await vm.collectPosts()
}
}
}

关于swiftui - 如何在 SwiftUI 中使用 async/await 链接 AnyPublisher,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72609975/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com