0

I writing async unit tests for RxSwift,this my code,I can't understand subscribe only once

class TestViewModel: NSObject {
    let result : Observable<Int>

     init(input:Observable<Int>) {
        result = input.flatMapLatest({ (value) -> Observable<Int> in

            return Observable.create({ (observer) -> Disposable in

                DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1, execute: {
                print("next"+"  \(value)")
                    observer.onNext(value)
                })

                return Disposables.create()
            })
        })
    }

}

    func testCount() {
        let expectation = XCTestExpectation(description: "async")
        let input = scheduler.createHotObservable([.next(100, 1),.next(200, 10)])
        let viewModel = TestViewModel.init(input: input.asObservable())
        viewModel.result.subscribe(onNext: { (value) in
            print("subscribe"+"   \(value)")
        }).disposed(by: disposeBag)
        scheduler.start()
        wait(for: [expectation], timeout: timeout)
    }  

print info:

next  1
next  10
subscribe   10  

I think print info should :

next  1
next  10
subscribe   1  
subscribe   10    

Someone can give me suggestion?thank

Karim
  • 322
  • 4
  • 20
  • 2
    Because of `flatMapLatest`. You instantly flatMap values into delayed observables. By using flatMap*Latest* you tell that you need only latest Observable's result and latest is 10 delayed for 1 second. Also, I would suggest to use Observable.timer instead of asyncAfter – Maxim Kosov May 17 '18 at 13:30
  • @MaximKosov Thank!you solved my problem – Karim May 17 '18 at 13:36

1 Answers1

1

It's how flatMapLatest operator works. Its basically tells "map events into observables but use only recent observable's result". So, you map your events into two observables:

1: --1sec-> 1

10: --1sec-> 10

Most recent observable at the moment is for 10.

Try to use flatMap instead of flatMapLatest.

You should also avoid Observable.create if possible. In your particular case (to delay a value) you could use Observable.timer or Observable.just(...).delay(...).

Maxim Kosov
  • 1,930
  • 10
  • 19