Yorn
Yorn

Reputation: 11

RxSwift map and flatMap

Why are the outputs of the two methods different? What is the reason for this?

When I use different combinations of operators, I expect to get the same output, but the result is not what I expect. I want to know the difference between using map and using flatMap here, and why it leads to different output

func test1() {
        let sb1 = RxRelay.BehaviorRelay(value: true)
        let sb2 = RxRelay.BehaviorRelay(value: 0)
        Observable.combineLatest(sb1, sb2)
            .filter {
                print("---filter----------")
                return $0 && $1 != -1
            }
            .debug("---debug")
            .observe(on: MainScheduler.asyncInstance)
            .take(1).map { $1 }
            .do(onNext: {
                print("---next value \($0)")
            })
            .do(onCompleted: {
                print("---send next")
                sb2.accept(12)
            })
            .subscribe()
            .disposed(by: disposeBag)
    }
    
    func test2() {
        let sb1 = RxRelay.BehaviorRelay(value: true)
        let sb2 = RxRelay.BehaviorRelay(value: 0)
        Observable.combineLatest(sb1, sb2)
            .filter {
                print("---filter----------")
                return $0 && $1 != -1
            }
            .debug("---debug")
            .observe(on: MainScheduler.asyncInstance)
            .take(1).flatMap { Observable.just($1) }
            .do(onNext: {
                print("---next value \($0)")
            })
            .do(onCompleted: {
                print("---send next")
                sb2.accept(12)
            })
            .subscribe()
            .disposed(by: disposeBag)
    }

Upvotes: 1

Views: 25

Answers (1)

Daniel T.
Daniel T.

Reputation: 33967

The problem you are seeing is because Relays, and the Subjects they are derived from, are not thread safe.

The solution is to push the observe(on:) operator as low as possible; in this case, just before the do(onCompleted:). This will ensure that as much of the stream as possible is handled synchronously. This is a general guideline from the Introduction to Rx book.

Better yet would be to avoid using Subjects and Relays...

Upvotes: 0

Related Questions