我目前正在将使用组合发布者的代码迁移到AsyncSequence。我以前使用这个和@Published
搜索查询一起使用,用户可以输入,现在尝试"组合"。基于AsyncSequence
的数据源的搜索项,如下所示(也使用values
将搜索查询转换为AsyncSequence
)。然而,我只看到flatMap
代码最初执行一次。
@MainActor
class FantasyPremierLeagueViewModel: ObservableObject {
@Published var playerList = [Player]()
@Published var query: String = ""
private let repository: FantasyPremierLeagueRepository
init(repository: FantasyPremierLeagueRepository) {
self.repository = repository
Task {
let playerStream = asyncStream(for: repository.playerListNative)
let filteredPlayerStream = $query
.debounce(for: 0.5, scheduler: DispatchQueue.main)
.values
.flatMap { query in
playerStream
.map { $0.filter { uery.isEmpty || $0.name.contains(query) } }
}
.map { $0.sorted { $0.points > $1.points } }
for try await data in filteredPlayerStream {
self.playerList = data
}
}
}
}
推入分支的代码,也可以在https://github.com/joreilly/FantasyPremierLeague/blob/kmp_native_coroutines/ios/FantasyPremierLeague/FantasyPremierLeague/ViewModel.swift
中查看好的,看起来这可以在一个更干净的方式使用combineLatest()
从新的Swift异步算法包(https://github.com/apple/swift-async-algorithms)。
Task {
let playerStream = asyncStream(for: repository.playerListNative)
.map { $0.sorted { $0.points > $1.points } }
for try await (players, searchQuery) in combineLatest(playerStream, $query.values) {
self.playerList = players
.filter { searchQuery.isEmpty || $0.name.localizedCaseInsensitiveContains(query) }
}
}