RxSwift中如何在Observable.create内部转发/返回Observable?
在自定义Observable的Observer中转发另一个Observable的正确方式
嘿,你的思路完全没问题,在RxSwift里确实可以这么实现,而且和你在RxJava里的经验是相通的!不过为了让代码更健壮、更符合RxSwift的风格,我来给你梳理两种靠谱的实现方式,以及需要注意的细节。
方式一:手动在create闭包中转发事件
这是最贴近你描述思路的实现,直接在自定义Observable的create闭包里处理弹窗回调,手动转发otherObservable的事件:
func performSomeActionAfterConfirmation() -> Observable<Void> { return Observable.create { [weak self] observer in guard let self = self else { observer.onCompleted() return Disposables.create() } let alert = UIAlertController(title: "确认操作", message: "确定要继续吗?", preferredStyle: .alert) var forwardDisposable: Disposable? let compositeDisposable = CompositeDisposable() // 点击Yes:订阅otherObservable并转发所有事件 let yesAction = UIAlertAction(title: "Yes", style: .default) { _ in forwardDisposable = self.otherObservable() .subscribe( onNext: { observer.onNext($0) }, onError: { observer.onError($0) }, onCompleted: { observer.onCompleted() } ) compositeDisposable.insert(forwardDisposable!) } // 点击No:直接完成当前Observable let noAction = UIAlertAction(title: "No", style: .cancel) { _ in observer.onCompleted() } alert.addAction(yesAction) alert.addAction(noAction) self.present(alert, animated: true) // 返回清理资源的Disposable:关闭弹窗+取消转发订阅 return Disposables.create { alert.dismiss(animated: true) compositeDisposable.dispose() } } } // 示例的otherObservable func otherObservable() -> Observable<Void> { return Observable.just(()).delay(.seconds(1), scheduler: MainScheduler.instance) }
这里要注意几个关键点:
- 用
[weak self]避免循环引用:create闭包会持有observer,而如果self持有这个Observable的话,很容易形成循环引用,weakify是必须的。 - 完整转发所有事件:不要只转发
onNext,必须把onError和onCompleted也传递给当前observer,否则如果otherObservable出错或者完成,订阅者会一直处于等待状态。 - 管理好Disposable:当外部订阅被取消时,要及时关闭弹窗并取消对
otherObservable的订阅,避免不必要的资源占用。
方式二:用flatMap组合Observable(更RxSwift风格)
如果你想让代码更简洁、更符合Rx的链式思维,可以把弹窗逻辑拆成一个独立的Observable,再用flatMap根据选择决定是否转发otherObservable:
func performSomeActionAfterConfirmation() -> Observable<Void> { // 第一步:创建处理弹窗选择的Observable let alertChoiceObservable = Observable<Bool>.create { [weak self] observer in guard let self = self else { observer.onCompleted() return Disposables.create() } let alert = UIAlertController(title: "确认操作", message: "确定要继续吗?", preferredStyle: .alert) let yesAction = UIAlertAction(title: "Yes", style: .default) { _ in observer.onNext(true) observer.onCompleted() } let noAction = UIAlertAction(title: "No", style: .cancel) { _ in observer.onNext(false) observer.onCompleted() } alert.addAction(yesAction) alert.addAction(noAction) self.present(alert, animated: true) return Disposables.create { alert.dismiss(animated: true) } } // 第二步:用flatMap根据选择转发Observable return alertChoiceObservable.flatMap { shouldProceed in shouldProceed ? self.otherObservable() : Observable.empty() } }
这种写法的优势:
- 逻辑拆分清晰:弹窗选择和业务逻辑(转发Observable)完全分离,可读性和维护性更好。
- 自动管理生命周期:
flatMap会自动处理内部Observable的订阅和取消,当外部订阅被取消时,内部的otherObservable订阅也会被自动清理,不需要手动管理Disposable。 - 代码更简洁:省去了手动转发事件的冗余代码,更符合RxSwift的设计理念。
总结
你在RxJava里的经验完全可以迁移到RxSwift中,核心思路都是在合适的时机订阅目标Observable并转发事件,或者用操作符组合Observable。只要注意内存管理(weak self)和事件完整性(转发所有onNext/onError/onCompleted),你的代码就会很可靠。
内容的提问来源于stack exchange,提问作者Ferran Maylinch
相关产品推荐
相关产品推荐

