I have a BehaviorRelay
setup to store an array of addresses, and then I observe that BehaviorRelay
so that I can create an MKAnnotation
array and then display that on the map.
let addresses = BehaviorRelay<[Address]>(value: [])
I make network requests when the user moves the map to a new area. If the user moves the map very quickly, I can end up with several network requests
I only want the latest response.
This is where my problem begins.
addresses.asObservable().subscribe(onNext: { [unowned self] (value) in
self.fetchAllAnnotationsAndAddToMap()
}).disposed(by: disposebag)
fetchAllAnnotationsAndAddToMap
gets called every time addresses is set.
fetchAllAnnotationsAndAddToMap
can take a long time to complete. Requests to run fetchAllAnnotationsAndAddToMap
get stacked up and all of them run to completion.
What I want to happen is once addresses
is set again, I want for all former calls to be discarded and only use the latest.
I've heard this is what flatMapLatest
is for.
However, flatMapLatest requires I return an observable and I'm confused by that.
How do I cancel the methods called after the BehaviorRelay
is updated and only use the most recent?
First you need to break up your fetchAllAnnotationsAndAddToMap()
function into two functions. Then you can:
addresses.asObservable()
// you might want to put a `debounce` call in here.
.flatMapLatest { addresses in
return fetchAllAnnotations(from: addresses)
}
.subscribe(onNext: { [weak self] annotations in
self?.addToMap(annotations)
}
.disposed(by: disposeBag)