Reputation: 11
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
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