RxSwift简单,没有最新触发

时间:2019-05-17 15:31:42

标签: ios swift rx-swift reactivex rx-cocoa

我有一个可观察的

//trying to reset state

  componentWillUnmount(){
    this.setState({click: 0})
  }

lazy var user = _user.share(replay: 1) private let _user = PublishRelay<User>() 单身。应用加载后,我的UserState.swift可观察对象就会收到一个事件,并且我会从后端收到一个用户。

稍后,在我的一个ViewModel中,我尝试

user

除非此事件永远不会触发(不要进入闭包内部),因为func profileViewModel( viewAppeared: Observable<Void> ) -> ( title: Observable<String> ) { let title = viewAppeared.withLatestFrom(UserState.shared.user) { _, user in user.username } return title } 在被订阅之前就已经触发了。

user事件中,我从可观察的事件中获取最新的viewDidLoad值时,如何实现此行为?

编辑:

在我的单例初始化中,如果我随机插入一个user,那么这一切都可行。我很困惑...

1 个答案:

答案 0 :(得分:1)

我看到了问题。 PublishRelay基本上只是一个PublishSubject。

viewModel订阅之前推送的所有内容都将丢失。 .share(replay:1)会有所帮助,不同之处在于在将用户推送到那个之前,需要订阅一些东西给那个,以便它“捕获”事件并为它缓存值以后的订阅者。

即使那样,您可能仍需要.share(重播:1,范围:.forever)。

您需要记住,您可以设置所需的所有可观察链,但是该链中的任何操作都不会执行,直到最终订阅该链。

将您的用户状态更改为BehaviorSubject (值:无)。即使没有用户订阅,也可以捕获并保留当前用户(如果有)。

然后在您的视图模型上执行以下操作。

class ProfileViewModel {
lazy var user = UserState.shared.user.compactMap { $0 }
lazy var name = user.map { $0.username }
lazy var age = user.map { "\($0.age) years old" }
   .do(onNext: { print($0) }
// etc
}

class profileViewController {
  ...
  override func viewDidLoad() {
    ...
    profileViewModel.name
      .subscribe(onNext: { [weak self] name in 
        self?.title = name
      }
      .disposed(by: disposeBag)
  }
}

请注意,如果在此视图控制器显示期间用户(以及用户名)可以动态更改,并且您希望标题自动更新,则需要这样做。

还要注意,如图所示,您永远不会在.do语句中看到用户的年龄,因为当前没有任何订阅或绑定到该可观察的子链。