RxSwift:嵌套可观察对象上的 FlatMap

Posted

技术标签:

【中文标题】RxSwift:嵌套可观察对象上的 FlatMap【英文标题】:RxSwift: FlatMap on nested observables 【发布时间】:2021-10-28 02:56:19 【问题描述】:

我有这个编辑器视图模型,我在其他不同的视图模型中使用它。父视图模型有一个可选择的用户,一旦选择了一个用户,我将需要一个带有新用户的编辑器的新实例。

这是编辑器和父级的简化版本。

class EditorViewModel 
    let user: String
    let item = PublishSubject<String>()
    
    init(user: String) 
        self.user = user
    



class ParentViewModel 
    var editor: Observable<EditorViewModel>!
    let user = BehaviorSubject<String?>(value: nil)
    
    init() 
        editor = user.compactMap  $0 .map  EditorViewModel(user: $0) 
    

一旦编辑器保存了一个项目,我希望通过flatMaping 编辑器到它的项目来获得保存的项目。像这样:

let parent = ParentViewModel()

parent.editor.flatMapLatest  $0.item .debug("item").subscribe(onNext:  item in
    print("This doesn't print")
)

parent.editor.subscribe(onNext:  editor in
    print("This one prints")
    editor.item.onNext("something")
)

parent.user.onNext("1")

flatMap 行确实订阅了,但它从来没有得到一个项目。

这是在操场上运行上述代码的输出:

2021-10-28 13:47:41.528: item -> subscribed
This one prints

另外,如果您认为这种设置过于疯狂,我同意并愿意接受建议。

【问题讨论】:

【参考方案1】:

默认情况下,Observables 是冷的。这意味着每个订阅都是独立工作的,在这种情况下,每个订阅都会获得不同的 EditorViewModel。 (.map EditorViewModel(user: $0) Observable 将为每个订阅调用其闭包。)

.map EditorViewModel(user: $0) Observable 之后添加.share().share(replay: 1) 会使其变热,这意味着所有订阅都将共享相同的效果。

至于您的子问题。我不认为我会设置这样的系统,除非这段代码之外的东西强迫我这样做。相反,我会将 Observable 传递给 EditorViewModel 而不是原始用户。这样您就无需在每次用户更改时重新构建编辑器视图模型。

【讨论】:

以上是关于RxSwift:嵌套可观察对象上的 FlatMap的主要内容,如果未能解决你的问题,请参考以下文章

RxSwift:在使用 flatMap 和 reduce 时需要帮助

RxSwift:结合不同类型的可观察对象和映射结果

RxSwift 将可观察对象数组与对象数组结合

RxSwift:返回一个带有错误的新可观察对象

来自数组的 RxSwift 可观察对象序列

为啥带有多个可观察对象的 RxSwift concat 似乎不起作用?