[RxSwift] flatMap vs flatMapLatest 的使用時機

[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


尚未有留言,成為第一個留言的人吧!

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *