Rxswift 在事件发生时取消观察者并重新订阅

Posted

技术标签:

【中文标题】Rxswift 在事件发生时取消观察者并重新订阅【英文标题】:Rxswift cancel observer when an event happen and resubcribe 【发布时间】:2018-10-08 07:43:21 【问题描述】:

您好,任何人都知道如何在事件发生时取消 observable 并重新订阅(基本上我希望 observable 在另一个事件发生时跳过发射(取消按钮点击)

详细场景:UISearchBar 上点击取消按钮,点击取消按钮时如何让 observable 暂停和停止发射事件?

我在想这样的事情:

Observable.of(searchClick,historyClick).merge().debounce(0.3, scheduler: scheduler)
                    .takeUntil(searchBar.rx.cancelButtonClicked)
                    .bind(to: viewModel.search)
                    .disposed(by: disposeBag)

但订阅在此之后停止。当事件发生时,我们如何重新订阅或以任何其他方式跳过发射?

【问题讨论】:

当单击取消按钮时,您所拥有的使 observable 停止发射。什么应该让它重新开始? 【参考方案1】:

我认为最好使用 '.switchLatest()' 运算符切换到下一个可观察对象(在切换时可能处于休眠状态)。

let eventSwitch: BehaviorSubject<Observable<T>> = BehaviorSubject.create(/*initial value*/) // where T is your type of choice
let events = eventSwitch.switchLatest() // subscribe consumer to this
eventSwitch.onNext(/*new event source of type Observable<T>*/) // call this from "Cancel" button

更新

let eventSwitch = BehaviorSubject(value: Observable
    .of(searchClick,historyClick)
    .merge()
    .debounce(0.3, scheduler: scheduler)
  )
let events = eventSwitch.switchLatest()

events
  .bind(to: viewModel.search)
  .disposed(by: disposeBag)

// call this from "Cancel" button
eventSwitch.onNext(...)
// argument can be empty observable or 'Observable.of(searchClick,historyClick).merge().debounce(0.3, scheduler: scheduler)'

【讨论】:

感谢您的回复。你能详细说明一下吗?当点击取消时我们如何防止这种可观察的发生:Observable.of(searchClick,historyClick).merge().debounce(0.3, scheduler: scheduler) 一旦你在 'eventSwitch.onNext(...)' 中提供了另一个 observable(甚至是一个空的!),订阅者将取消订阅前一个 observable。在您的情况下,主订阅将类似于“events.bind(to: viewModel.search).disposed(by: disposeBag)” - 请参阅更新。 可以帮助检查第一个let的语法。收到错误:无法将“Observable”类型的值转换为预期的参数类型“(AnyObserver<_>) -> Disposable” 您好应用我们的建议,但是当点击取消按钮时,observable 仍然会触发。单击取消时,我们会跳过火灾 在你调用了'eventSwitch.onNext(Observable.empty())'之后?

以上是关于Rxswift 在事件发生时取消观察者并重新订阅的主要内容,如果未能解决你的问题,请参考以下文章

设计模式--观察者模式(发布订阅模式)

第十一篇 手写原理代码

观察者在单元格 RxSwift 中处理后仍然接收事件

有没有办法在它发生时取消 jQuery 的悬停事件?

当我的 UIPanGestureRecognizer 与 UIScrollView 一起发生时,如何取消其他事件?

RxSwift