2017-05-24 5 views
1

Je m'attendais à voir timer -> Event completed être sorti juste après avoir vu running -> Event completed mais cela ne s'est pas produit.Rx flatMapLatest ne passe pas terminé à travers?

Quelqu'un peut-il expliquer pourquoi et me donner une idée sur la façon de compléter le timer observable?

/// playground 

import RxSwift 
import PlaygroundSupport 
PlaygroundPage.current.needsIndefiniteExecution = true 


struct TimerCountdown { 

    let timer: Observable<Int> 

    init(running: Observable<Bool>) { 
     timer = running.flatMapLatest { $0 ? Observable<Int>.interval(1.0, scheduler: MainScheduler.instance) : Observable<Int>.never() } 
    } 

} 

let running = PublishSubject<Bool>() 
let countdown = TimerCountdown(running: running) 

_ = running.debug("running").subscribe() 

_ = countdown.timer.debug("timer").subscribe() 

running.onNext(true) 
DispatchQueue.main.asyncAfter(deadline: .now() + 3.5) { 
    running.onNext(false) 
} 

DispatchQueue.main.asyncAfter(deadline: .now() + 7.5) { 
    running.onNext(true) 
} 

DispatchQueue.main.asyncAfter(deadline: .now() + 10.5) { 
    running.onCompleted() 
} 

Répondre

2

Ceci est la solution que je trouve:

struct TimerCountdown { 

    let timer: Observable<Int> 

    init(running: Observable<Bool>) { 
     timer = running 
      .flatMapLatest { $0 ? Observable<Int>.interval(1.0, scheduler: MainScheduler.instance) : Observable<Int>.never() 
      } 
      .takeUntil(running.materialize().filter { $0.isCompleted }) 
    } 
}