func someCompletable() -> Completable {
return Completable.create { observer in
observer(.completed)
return Disposables.create()
}
}
let buttonDidTap = PublishRelay<Void>()
buttonDidTap
.debug()
.subscribe()
.disposed(by: disposeBag)
我看到在点击 buttonDidTap 时触发了 next() 事件。
但是,当我通过 flatMap 将其转换为 Completable 类型时,flatMap 之后没有发出任何事件。
buttonDidTap
.flatMap { self.someCompletable() }
.debug()
.subscribe()
.disposed(by: disposeBag)
我也试过订阅所有事件 onNext、onCompletable、onError 和 onDisposed,但它们都没有发出。 知道这是为什么吗?
这是一个 gif 运行屏幕 :https://user-images.githubusercontent.com/57667738/229386647-c061d185-2015-40af-9150-5daac58c47ec.gif
buttonDidTap
.debug() //onNext event fired
.flatMap { self.someCompletable() }
.debug() //no event fired
.subscribe()
.disposed(by: disposeBag)
我的猜测是flatMap在将Completable转换为Observable的过程中失去了Completable的特性,还原为Observable的形式。 因此,对 onCompleted 的调用似乎消失了。 我该如何解决这个问题?
flatMap
在它跟随的每个可观察对象完成之前无法完成。否则它将无法响应任何更多事件。例如,下次点击按钮时。
所以当 completable 发出一个 completed 事件时,flatMap 应该做什么?
出于这个原因,您看不到任何事件从 flatMap 中发出(直到链上游进一步发出错误或所有可完成的订阅和可观察到的按钮点击已完成。)
如果您想知道可完成事件何时真正完成,您需要将已完成的事件转换为下一个事件。例如:
buttonDidTap
.flatMap { someCompletable.andThen(Observable.just(())) }
这样,每次
.next(())
完成时,从 flatMap 返回的 observable 都会发出一个 someCompletable
事件。
您发布的代码:
buttonDidTap
.debug() //onNext event fired
.flatMap { self.someCompletable() }
.debug() //no event fired
.subscribe()
.disposed(by: disposeBag)
可能有一个保留周期。由于传递给
flatMap
的闭包保留了 self
并且 disposeBag 由 self
保留。这意味着self
切向保留自己。
要删除循环,请在闭包外部创建 Completable:
let completable = someCompletable()
buttonDidTap
.debug() //onNext event fired
.flatMap { completable }
.debug() //no event fired
.subscribe()
.disposed(by: disposeBag)
之所以可行,是因为每次订阅 Completable 时,它都会调用您传递给其构造函数的闭包。