You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:12:05