【问题标题】:How to return/forward an observable inside Observable.create (RxSwift)如何在 Observable.create (RxSwift) 中返回/转发一个 observable
【发布时间】:2025-11-24 18:35:01
【问题描述】:

我想知道向我创建的 observable 的观察者“转发”(如果这是术语)一个 observable 的正确方法是什么。

下面是一个例子。

我的函数 performSomeActionAfterConfirmation 显示一个 UIAlertController 并返回一个新的 observable。如果在警报控制器中选择“是”,我将“转发”otherObservable() 给创建的 observable 的观察者。如果选择“否”,我只是完成 observable。

我想我的代码会起作用,因为我在 RxJava 中做过类似的事情,但在这种情况下,我在 self?.otherObservable().subscribe(observer) 收到警告说“未使用 'subscribe' 调用的结果”。

我想我必须将它分配给 DisposeBag,但我不知道如何,因为该包由 performSomeActionAfterConfirmation 的调用者管理。也许我应该将它作为参数传递给函数?

func performSomeActionAfterConfirmation() -> Observable<String> {

    return Observable<String>.create { [weak self] observer in

        let alertCtrl = UIAlertController(title: "perform action", message: "do it?", preferredStyle: .alert)

        // yes -> forward another observable
        alertCtrl.addAction(UIAlertAction(title: "yes", style: .default, handler: { _ in
            self?.otherObservable().subscribe(observer) // Result call is unused
        }))

        // no -> just complete this observable
        alertCtrl.addAction(UIAlertAction(title: "no", style: .default, handler: { _ in
            observer.onCompleted()
        }))

        self?.host?.present(alertCtrl, animated: true)

        return Disposables.create()
    }
}

func otherObservable() -> Observable<String> {
    return Observable.empty() // dummy code
}

【问题讨论】:

    标签: swift rx-swift


    【解决方案1】:

    我相信是的,您可以将“外部”处理包传递到您的函数中。这是必需的,因为您的观察者基本上将订阅 2 个序列。一种是main,只有在选择“no”时才能调用complete,一种是inner,可以发出自己的事件。

    但我相信实现您的预​​期行为的更简单的方法是逐步实现。我的意思是:

    func performSomeActionAfterConfirmation() -> Observable<String> {
    
        return Observable<Void>.create { [weak self] observer in
            let alertCtrl = UIAlertController(title: "perform action", message: "do it?", preferredStyle: .alert)
    
            // yes -> emit one event and complete
            alertCtrl.addAction(UIAlertAction(title: "yes", style: .default, handler: { _ in
                observer.onNext()
                observer.onCompleted()
            }))
    
            // no -> just complete
            alertCtrl.addAction(UIAlertAction(title: "no", style: .default, handler: { _ in
                observer.onCompleted()
            }))
    
            self?.host?.present(alertCtrl, animated: true)
            return Disposables.create()
        }
        .flatMap { [weak self] _ -> Observable<String> in
            guard let `self` = self else { return .empty() }
            return self.otherObservable()
        }
    }
    
    func otherObservable() -> Observable<String> {
        return Observable.empty() // dummy code
    }
    

    【讨论】:

    • 感谢您的回答。它给了我一些想法。我已经在考虑将UIAlertController 变成Observable。我看到您在第一步中或多或少地这样做,然后在第二步中将可观察到的平面映射到所需的结果。实际上,我最终创建了那个 Observable。我不确定 SwiftRx 是否已经附带,但这是另一个问题。 :)
    • 如果有人有兴趣将UIAlertController 变成Observablecheck here
    最近更新 更多