【问题标题】:RxSwift: Repeat a (completed) streamRxSwift:重复(完成)流
【发布时间】:2026-01-03 09:45:01
【问题描述】:

假设我有一个可用于启动和停止(切换)动作的按钮。

let toggleStream: Observable<Bool> = toggleBtn.rx.tap.scan(false) { state, _ in !state }

我有另一个流,它连续发出整数。

let emitter = Observable<Int>.interval(2.0, scheduler: timerScheduler)

现在我想使用切换流来启动和停止第二个流的发射。这是我的方法:

Observable.combineLatest(toggleStream, emitter) { shouldEmit, evt in
    return (shouldEmit, evt)
}.takeWhile{ (shouldEmit, evt:Int) in
    return shouldEmit == true
}.map {(_, evt) in
    return evt
}

这是第一次很好用。我可以按下按钮,Observable 开始发射它的Ints。也停止工作。可悲的是,我无法再次启动它,因为流已完成。当用户再次切换按钮时,如何重新启动/重试/重复?

【问题讨论】:

    标签: swift3 observable rx-swift reactivex rx-cocoa


    【解决方案1】:

    这是我在操场上的做法。您应该能够推断:

    //: Playground - noun: a place where people can play
    
    import RxSwift
    
    let toggleButton = PublishSubject<Void>()
    let toggleStream: Observable<Bool> = toggleButton
        .scan(false) { state, _ in !state }
        .debug()
        .shareReplayLatestWhileConnected()
    
    let emit = toggleStream
        .filter { $0 }
        .flatMapLatest { _ in
            Observable<Int>.interval(2.0, scheduler: MainScheduler.instance)
                .takeUntil(toggleStream.filter { !$0 })
        }
    
    
    _ = emit.subscribe( {
        print($0)
    })
    
    toggleButton.onNext()
    DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 5.0) {
        toggleButton.onNext()
    }
    DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 11.0) {
        toggleButton.onNext()
    }
    DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 17.0) {
        toggleButton.onNext()
    }
    
    import PlaygroundSupport
    PlaygroundPage.current.needsIndefiniteExecution = true
    

    【讨论】: