iOS Combine框架debounce操作符如何在计时结束前手动触发事件?
实现方案
方案1:抽取公共逻辑(最简便)
把sink中的业务逻辑单独封装为独立方法,正常debounce触发和手动触发都直接调用该方法即可:
var subject = PassthroughSubject<Void, Never>() var cancellable: Cancellable! // 抽取独立的业务逻辑方法 func doSomething() { // 原有sink中的逻辑 } cancellable = subject .debounce(for: .seconds(0.1), scheduler: RunLoop.main) .sink { doSomething() } // 需要手动触发时直接调用即可 // doSomething()
该方案改动最小,不需要调整Combine链路,适合大多数场景。
方案2:合并Publisher流
如果需要保持整个响应式链路的一致性,不需要脱离Publisher触发,可以新增一个手动触发的Subject,将debounce后的流和手动触发流合并后统一订阅:
var subject = PassthroughSubject<Void, Never>() // 新增手动触发专用Subject var manualTrigger = PassthroughSubject<Void, Never>() var cancellable: Cancellable! cancellable = Publishers.Merge( subject.debounce(for: .seconds(0.1), scheduler: RunLoop.main), manualTrigger ) .sink { // doSomething } // 需要手动触发时调用 // manualTrigger.send(())
这种方式下两种触发路径都走同一个sink回调,业务逻辑完全一致,不会出现逻辑遗漏。
注意:如果手动触发后需要避免未完成的debounce计时到期后重复执行业务逻辑,可以在业务逻辑里加标志位判断,或者手动触发后调用
cancellable.cancel()后重建订阅链路即可。
内容的提问来源于stack exchange,提问作者Laufwunder
相关产品推荐
相关产品推荐

