You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在PassthroughSubject发出nil时取消flatMap的Timer.publisher?

解决方案

你可以通过在flatMap的闭包中根据value是否为nil返回不同的发布者来实现需求:

情况1:收到nil时停止当前Timer,后续仍可响应非nil值

修改flatMap逻辑,当value为nil时返回一个立即完成的空发布者,这样会自动取消之前的Timer订阅,停止计时:

let stream = PassthroughSubject<String?, Never>()
let repeated = stream.flatMap { value -> AnyPublisher<Date, Never> in
    guard value != nil else {
        // 返回立即完成的空发布者,终止当前Timer
        return Empty(completeImmediately: true).eraseToAnyPublisher()
    }
    return Timer.publish(every: 3, on: .main, in: .default)
        .autoconnect()
        .eraseToAnyPublisher()
}

情况2:收到nil后彻底终止整个发布链,不再处理后续事件

如果希望一旦收到nil,整个repeated发布者就永久终止,不再响应后续的非nil值,可以结合prefix(while:)操作符:

let stream = PassthroughSubject<String?, Never>()
let repeated = stream
    .prefix(while: { $0 != nil }) // 当检测到nil时,终止上游发布者
    .flatMap { _ in
        Timer.publish(every: 3, on: .main, in: .default)
            .autoconnect()
    }

原理说明

  • Empty(completeImmediately: true)会立即发送完成事件,flatMap在切换到这个发布者时,会自动取消之前订阅的Timer,从而停止计时。
  • prefix(while:)会让发布者在满足条件(这里是value != nil)时继续发送事件,一旦条件不满足,就发送完成事件,终止整个链的所有订阅。

内容的提问来源于stack exchange,提问作者Yotam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 01:55:32