How can I wait for do1 to complete first, then execute do2, then do3?
I think concatMap solves the problem.
Lets say we have some service and some actions we need to perform on it, for instance a backend against with we'd like to authenticate and store some data. Actions are login and store. We can't store any data if we aren't logged in, so we need to wait login to be completed before processing any store action.
While flatMap, flatMapLatest and flatMapFirst execute observables in parallel, concatMap waits for your observables to complete before moving on.
import Foundation
import RxSwift
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
let service: [String:Observable<String>] = [
"login": Observable.create({
observer in
observer.onNext("login begins")
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0, execute: {
observer.onNext("login completed")
observer.onCompleted()
})
return Disposables.create()
}),
"store": Observable.create({
observer in
observer.onNext("store begins")
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2, execute: {
observer.onNext("store completed")
observer.onCompleted()
})
return Disposables.create()
}),
]
// flatMap example
let observeWithFlatMap = Observable.of("login", "store")
.flatMap {
action in
service[action] ?? .empty()
}
// flatMapFirst example
let observeWithFlatMapFirst = Observable.of("login", "store")
.flatMapFirst {
action in
service[action] ?? .empty()
}
// flatMapLatest example
let observeWithFlatMapLatest = Observable.of("login", "store")
.flatMapLatest {
action in
service[action] ?? .empty()
}
// concatMap example
let observeWithConcatMap = Observable.of("login", "store")
.concatMap {
action in
service[action] ?? .empty()
}
// change assignment to try different solutions
//
// flatMap: login begins / store begins / store completed / login completed
// flatMapFirst: login begins / login completed
// flatMapLatest: login begins / store begins / store completed
// concatMap: login begins / login completed / store begins / store completed
let observable = observeWithConcatMap
observable.subscribe(onNext: {
print($0)
})