【问题标题】:How to observe upper Observables with flatMap in RxSwift?如何在 RxSwift 中使用 flatMap 观察上层 Observable?
【发布时间】:2020-05-22 03:59:56
【问题描述】:

mapflatMap 之间的差异RxSwift 已解释here。现在我想在内部可观察对象发生变化时观察上部可观察实例。 我该怎么做?

我们来看例子,

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 { $0.score.asObservable() }
        .subscribe(onNext: { print($0) })
        .disposed(by: bag)

    player.on(.next(male))
    male.score.on(.next(100))
}

在上面的例子中,输出是,

80
100

正如预期的那样。但我想知道订阅块.subscribe(onNext: { print($0) }) 内的完整播放器对象状态(即播放器的age),但它只得到score我该怎么做?

我的预期输出是,

Player (where I can access both age:28 and score:80)
Player (where I can access both age:28 and score:100)

【问题讨论】:

    标签: ios swift reactive-programming rx-swift flatmap


    【解决方案1】:

    您从flatMap 返回一个可观察的分数,因此下游只有一个分数可用。相反,您想返回一个可观察的玩家信息。您可以通过使用额外的 map 运算符并关闭玩家参数来将年龄附加到分数:

    player.asObservable()
          .flatMap { p in
              p.score.asObservable()
                     .map { score in (age: p.age, score: p.score) } }
          .subscribe(onNext: { print($0) })
          .disposed(by: bag)
    

    【讨论】:

    • 您的建议有效,但有没有其他更清洁的方法可以避免map
    • 我不知道。也许有一些基本相同的 rx 运算符,或者您可以将其包装到自定义 rx 运算符中。这几乎是标准的方法。像 scala 或 c# 这样的语言使用理解语法来使其更简洁,但它在引擎盖下的工作原理是一样的。
    【解决方案2】:

    另一种选择是:

    player.asObservable()
        .flatMap { Observable.combineLatest(Observable.just($0.age), $0.score.asObservable()) }
    

    从类别理论 POV 来看,这被认为是一种更清洁的方法(您正在将年龄值“提升”到 monad 中),但是 YMMV。

    此外,主题永远不应该在var 中,它们应该始终是lets。用不同的主题替换主题是没有意义的。

    从长远来看,从你的 Player 结构中删除主题可能会更好:

    struct Player {
        var age: Int
        var score: Int
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-01-30
      • 1970-01-01
      • 1970-01-01
      • 2017-12-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多