我是rxswift的新手,这是我的问题:
假设我有可观察的动作:Observable.of(“do1”,“do2”,“do3”)
现在这个observable映射到返回observable的函数:
let actions = Observable.of("do1", "do2", "do3")
func do(action: String) -> Observable<Result> {
// do something
// returns observable<Result>
}
let something = actions.map { action in return do(action) } ???
我如何等待do1先完成,然后执行do2,然后执行do3?
编辑:基本上我想实现动作的顺序执行。 do3等待do2结果,do2等待do1结果。
Edit2:我尝试过使用flatmap和subscribe,但所有操作都是并行运行。
答案 0 :(得分:1)
我如何等待do1先完成,然后执行do2,然后执行do3?
我认为concatMap
解决了这个问题。
假设我们有一些服务和一些我们需要对其执行的操作,例如我们想要验证和存储一些数据的后端。操作登录和商店。如果我们未登录,我们无法存储任何数据,因此我们需要等待登录完成,然后才能处理任何商店操作
当flatMap
,flatMapLatest
和flatMapFirst
并行执行可观察对象时,concatMap
会等待您的可观察对象完成后再继续。
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)
})
答案 1 :(得分:0)
使用flatMap
或flatMapLatest
。您可以在reactivex.io找到有关它们的更多信息。
答案 2 :(得分:0)
您可以通过在最终输出上调用flatMap
来subscribe
和Result
subscribe(on:)
可观察序列。
actions
.flatMap { (action) -> Observable<Result> in
return self.doAction(for: action)
}
.subscribe(onNext: { (result) in
print(result)
})
func doAction(for action: String) -> Observable<Result> {
//...
}
读:
答案 3 :(得分:0)
我只是面临同样的问题,终于找到了解决方案。 我希望我的设备会先断开连接,然后执行以下操作:
我只是创建像这样的功能
func disconnect(position: WearingPosition) -> Completable{
print("test run")
return Completable.create { observer in
print("test run 2")
// Async process{
// observer(.complete)
// }
return Disposables.create()
}
}
并使用类似:
self.disconnect(position: .left_wrist).andThen(Completable.deferred({
return self.disconnect(position: .right_wrist)
})).subscribe(onCompleted: {
// do some things
}) { (error) in
print(error)
}.disposed(by: self.disposeBag)
关键是“ Completable.deferred”的用法
我已经测试了印刷的“测试运行”