如何丢弃旧值获取最新值?Combine是否有类似Kotlin getLatest的操作符
Combine中实现类似Kotlin getLatest的功能
在Combine框架里,和Kotlin的getLatest功能对应的是switchToLatest操作符。它的核心作用是:当上游流发送新的事件时,立刻取消之前还在处理的订阅任务,只专注处理最新的那个事件,完全符合你“丢弃旧项、仅处理最新输入”的需求。
针对你的搜索场景说明
你当前的代码里,map中的过滤是同步操作,其实不会出现旧任务堆积的问题——因为每输入一个字符,同步过滤会立刻完成,新的输入会直接覆盖之前的结果。但如果你的搜索逻辑改成异步(比如调用网络接口获取匹配的国家),这时候就必须用switchToLatest来避免旧请求返回干扰最新结果。
修改后的代码示例(模拟异步场景)
class Foo: ObservableObject { @Published var searchText = String() @Published var countries = [Country]() let allCountries: [Country] = [.init(name: "France"), .init(name: "Paraguay")] init() { $searchText // 将同步过滤包装成异步任务(模拟网络请求) .map { [weak self] text in return Future<[Country], Never> { promise in // 模拟异步延迟 DispatchQueue.global().asyncAfter(deadline: .now() + 0.1) { let result = text.isEmpty ? self?.allCountries : self?.allCountries.filter { $0.name.contains(text) } promise(.success(result ?? [])) } } } // 使用switchToLatest,丢弃旧的异步任务,只处理最新的 .switchToLatest() .assign(to: &$countries) } } struct Country { var name: String }
关键点解释
switchToLatest要求上游流发送的是Publisher类型(比如上面的Future),它会自动订阅最新的Publisher,并取消之前的订阅。- 如果你的搜索逻辑一直是同步的,其实不需要额外操作,但保留
switchToLatest的写法也能让代码更健壮,方便后续扩展为异步逻辑。
内容的提问来源于stack exchange,提问作者ASA
相关产品推荐
相关产品推荐

