如何在 RxSwift 中使用 flatMap 观察上层 Observables?
How to observe upper Observables with flatMap in RxSwift?
RxSwift
的 map
和 flatMap
之间的区别已经解释 。现在我想在内部可观察对象发生变化时观察上层可观察实例。 我该怎么做?
让我们看例子,
func testFlatMap() {
let bag = DisposeBag()
struct Player {
var age: Int
var score: BehaviorSubject<Int>
}
let male = Player(age: 28, score: BehaviorSubject(value: 80))
let player = PublishSubject<Player>()
player.asObservable()
.flatMap { [=10=].score.asObservable() }
.subscribe(onNext: { print([=10=]) })
.disposed(by: bag)
player.on(.next(male))
male.score.on(.next(100))
}
在上面的例子中,输出是,
80
100
符合预期。但我想知道订阅块 .subscribe(onNext: { print([=17=]) })
内的完整玩家对象状态(即玩家的 age
),但它只获得 score
。 我该怎么做?
我的预期输出是,
Player (where I can access both age:28 and score:80)
Player (where I can access both age:28 and score:100)
您 return 从 flatMap
中观察分数,因此只有一个分数可用于下游。相反,您想要 return 可观察到的玩家信息。您可以通过使用额外的 map
运算符并关闭玩家参数来将年龄附加到分数:
player.asObservable()
.flatMap { p in
p.score.asObservable()
.map { score in (age: p.age, score: p.score) } }
.subscribe(onNext: { print([=10=]) })
.disposed(by: bag)
另一种选择是:
player.asObservable()
.flatMap { Observable.combineLatest(Observable.just([=10=].age), [=10=].score.asObservable()) }
从类别理论 POV 来看,这被认为是一种更简洁的方法(您将 "lifting" 年龄值放入 monad,)但是 YMMV。
另外,Subjects 不应该被保存在 var
,它们应该总是 let
s。用不同的主题替换主题是没有意义的。
从您的 Player 结构体中移除主题并使其成为:
可能会更好 运行
struct Player {
var age: Int
var score: Int
}
RxSwift
的 map
和 flatMap
之间的区别已经解释
让我们看例子,
func testFlatMap() {
let bag = DisposeBag()
struct Player {
var age: Int
var score: BehaviorSubject<Int>
}
let male = Player(age: 28, score: BehaviorSubject(value: 80))
let player = PublishSubject<Player>()
player.asObservable()
.flatMap { [=10=].score.asObservable() }
.subscribe(onNext: { print([=10=]) })
.disposed(by: bag)
player.on(.next(male))
male.score.on(.next(100))
}
在上面的例子中,输出是,
80
100
符合预期。但我想知道订阅块 .subscribe(onNext: { print([=17=]) })
内的完整玩家对象状态(即玩家的 age
),但它只获得 score
。 我该怎么做?
我的预期输出是,
Player (where I can access both age:28 and score:80)
Player (where I can access both age:28 and score:100)
您 return 从 flatMap
中观察分数,因此只有一个分数可用于下游。相反,您想要 return 可观察到的玩家信息。您可以通过使用额外的 map
运算符并关闭玩家参数来将年龄附加到分数:
player.asObservable()
.flatMap { p in
p.score.asObservable()
.map { score in (age: p.age, score: p.score) } }
.subscribe(onNext: { print([=10=]) })
.disposed(by: bag)
另一种选择是:
player.asObservable()
.flatMap { Observable.combineLatest(Observable.just([=10=].age), [=10=].score.asObservable()) }
从类别理论 POV 来看,这被认为是一种更简洁的方法(您将 "lifting" 年龄值放入 monad,)但是 YMMV。
另外,Subjects 不应该被保存在 var
,它们应该总是 let
s。用不同的主题替换主题是没有意义的。
从您的 Player 结构体中移除主题并使其成为:
可能会更好 运行struct Player {
var age: Int
var score: Int
}