[RxSwift] flatMap vs flatMapLatest
相較於 flatMap 會全部訂閱事件, flatMapLatest 則只會訂閱最新的事件,取消訂閱上一個事件
flatMapLatest 使用場景一:
當 subject 裡面又有另一個 subject,使用 flatMap 會導致過去訂閱的 subject 會重複被使用
範例一
struct Person {
var age : BehaviorRelay<Int>
}
-----------------------------------------------
let mark = Person(age: BehaviorRelay(value: 33))
let lily = Person(age: BehaviorRelay(value: 20))
let checker = PublishSubject<Person>()
checker.flatMap { person in // 可以替換成 flatMaplatest 試看看
return person.age
}.subscribe(onNext:{
print($0)
}).disposed(by:bag)
checker.onNext(mark)
mark.age.accept(35)
checker.onNext(lily)
lily.age.accept(40)
mark.age.accept(41)
// 33 -> 初始值
// 35 -> mark 更新 age
// 20 -> 初始值
// 40 -> lily 更新 age
// 41 -> mark 更新 age, 如果是 flatMap 就還是會 print 出,而改成 flatMapLatest 就不會了
範例二
當 API request 因為 asyncAfter 的延遲(模擬 response time) 還沒被執行時,又有下一次的 request 產生就會先 cancel 上一次的
let disposeBag = DisposeBag()
class API {
func request(value:String) -> Single<String> {
.create { (single) -> Disposable in
print("request call:\(value)")
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
single(.success((value)))
}
return Disposables.create()
}
}
}
let subject = PublishSubject<String>()
// 1
subject.flatMap { API().request(value: $0) }
.debug("Call API")
.subscribe( { value in
print(value)
})
.disposed(by: disposeBag)
// 2
subject.onNext(("a"))
// 3
delay(2) {
subject.onNext(("b"))
}
// 4
delay(3) {
subject.onNext(("c"))
}
=== console log ===
request call:a
next(a)
request call:b
request call:c
next(b)
next(c)
如果換成 flatMapLatest 就是:
=== console log ===
request call:a
next(a)
request call:b
request call:c
next(c)
網頁瀏覽量: 4