RxSwift 简单 withLatestFrom 不触发
Posted
技术标签:
【中文标题】RxSwift 简单 withLatestFrom 不触发【英文标题】:RxSwift simple withLatestFrom not firing 【发布时间】:2019-05-17 15:31:42 【问题描述】:我有一个可观察的
lazy var user = _user.share(replay: 1)
private let _user = PublishRelay<User>()
在UserState.swift
单例中。我的user
observable 在应用程序加载后立即收到一个事件,并且我从后端收到一个用户。
稍后,在我的一个 ViewModel 中,我尝试
func profileViewModel(
viewAppeared: Observable<Void>
) -> (
title: Observable<String>
)
let title = viewAppeared.withLatestFrom(UserState.shared.user) _, user in
user.username
return title
除非此事件永远不会触发(不要进入闭包),因为user
在订阅之前已经触发。
如何在 viewDidLoad
事件中完成此行为,我从我的 observable 中获取最新的 user
值?
编辑:
在我的单例初始化中,如果我随机输入一个user.subscribe()...
,那么这一切都有效。我很困惑...
【问题讨论】:
你订阅了withLatestFrom
返回的observable吗?
更新了答案以说明编辑代码中提供的新线索。见下文:
【参考方案1】:
我看到了问题。 PublishRelay 基本上只是一个 PublishSubject。
在您的 viewModel 订阅之前推送到它的任何内容都将丢失。 .share(replay: 1) 会有所帮助,除了在用户被推送到它之前需要订阅 that 的东西,以便它“捕获”事件并缓存后来的订阅者。
即使那样你也可能需要 .share(replay: 1, scope: .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 语句中看到用户的年龄,因为目前没有订阅或绑定到该可观察子链。
【讨论】:
嗯,我尝试了share(replay:1)
路由,但似乎仍然没有触发我的流。
我编辑了一些帖子,我的 VC 在 viewDidLoad() 上调用了这个 viewModel 方法
@Brejuro 弄清楚发生了什么。查看修改后的答案。以上是关于RxSwift 简单 withLatestFrom 不触发的主要内容,如果未能解决你的问题,请参考以下文章
如何从 rxjs 6 withLatestFrom 键入数组映射参数
[RxJS] Combination operator: withLatestFrom