RxSwift。如何响应一系列的通知?

问题描述 投票:1回答:1

假设我有两个通知接踵而至。我需要等待第一个通知的工作完成,然后才从第二个通知中启动工作。目前,我尝试将序列调度到串行调度器,但并没有像预期的那样工作,似乎我错过了什么。

NotificationCenter.default.rx.notification(.notification1)
  .observeOn(MainScheduler.instance)
  .subscribe(onNext: { [weak self] in
     self?.doSomeAsynchWork() //Fires another subscription, kind of ugly
  })
  .disposed(by: disposeBag)


NotificationCenter.default.rx.notification(.notification2)
  .observeOn(MainScheduler.instance)
  .subscribe(onNext: { [weak self] in
     self?.doSomeWork() //This should only be executed after doSomeAsynchWork() is done
  })
  .disposed(by: disposeBag)

我期待工作能以串行方式完成,但事实并非如此,我猜测是 doSomeAsynchWork() 是,嗯,异步和 doSomeWork() 之后立即开火。但我能不能以某种方式等待异步工作完成?感谢任何帮助

更新:notification2可能会到,也可能不会到,所以它们之间算是相互独立的。另外,notification1可能会到,也可能不会到,只是应用中的用例不同。但当notification1和notification2同时出现时,我需要等待的是 doSomeAsynchWork() 完成

流程如下。

  1. 用户点击屏蔽列表中的某些元素,只有登录用户才可以使用。
  2. 用户被重定向到一个登录界面
  3. 用户唱进,然后,notification1就开火了。
  4. 现在我们签到了,就继续屏蔽这个元素。
  5. 通知2发射

问题是当notification1发射时,我们需要重新加载屏幕,所以这个逻辑就到了doSomeAsynchWork()。除此之外,我们在收到 "删除元素 "的通知时,我们试图定位这个还不存在的元素,所以我们有点陷入了不一致的状态,元素被屏蔽了,但仍然存在于屏幕上

困难的是,我们可以签到而不屏蔽元素,我们可以屏蔽元素而不需要签到(因为我们已经签到了,比如)

swift rx-swift
1个回答
0
投票

根据你在更新中描述的流程,我希望看到这样的情况。

func example(tapElement: Observable<ID>, isLoggedIn: Observable<Bool>, presentLogin: Observable<Void>) {
    tapElement
        .withLatestFrom(isLoggedIn) { (id: $0, isLoggedIn: $1) }
        .flatMapFirst { id, isLoggedIn in
            isLoggedIn ? Observable.just(id) : presentLogin.map { id }
        }
        .subscribe(onNext: { id in
            blockElement(id: id)
        })
}

我看不出有什么理由要把所有的通知都放在首位。


旧答案

我本来 doSomeAsynchWork() 回报 Observable<Void> 的事件,并发出异步工作完成的消息。这样我就可以了。

NotificationCenter.default.rx.notification(.notification1)
    .flatMap { doSomeAsynchWork() }
    .subscribe(onNext: { doSomeWork() }

另一个选择是让 doSomeAsynchWork() 归还 Completable那你就会做这样的事情。

NotificationCenter.default.rx.notification(.notification1)
    .flatMap { doSomeAsynchWork() }
    .subscribe(onCompleted: { doSomeWork() }
© www.soinside.com 2019 - 2024. All rights reserved.