Assume I have array of Ints:
var items = [1, 2, 3, 4, 5]
and a function that takes Int argument and basing on it sends network request:
func sendRequest(argument: Int) -> Observable<Void> {
// sends network request
...
}
I want to send network requests for each element of items array, but I want to do it sequentially, send next request only once previous one is finished.
My first attempt was something like this:
let observables = items.map{ [weak self] argument in (self?.sendRequest(argument: argument) ?? Observable.empty()) }
let result = Observable.concat(observables)
This approach however sends request simultaneously and only combine the results sequentially.
My second approach:
let items = [1, 2, 3, 4, 5]
var result = Observable.just(Void())
for item in items {
result = result.flatMap{ [weak self] in
self?.sendRequest(argument: item) ?? Observable.empty()
}
}
It seems to work, but obviously result emits next element only once all network requests finish.
What I would need is sending requests sequentially with result observable that emits next event once each single request is finished.
Any suggestions?
Operator .concatMap()
guarantees that order remains intact, as opposed to .flatMap()
i.e.
Observable.from([1,2,3,4,5]).concatMap( /* your request code */ )
UPDATE
let source = Observable.from([1,2,3,4,5])
let trigger = BehaviorSubject<Int>(value: 0)
let feed = Observable.zip(source, trigger) { return $0.0 }
feed.concatMap {
/* your request code */
trigger.onNext(0) // possibly in .onComplete of the service call
}
来源:https://stackoverflow.com/questions/47906030/rxswift-how-to-chain-observables-sequentially