如何在 Observable.create (RxSwift) 中返回/转发一个 observable

Posted

技术标签:

【中文标题】如何在 Observable.create (RxSwift) 中返回/转发一个 observable【英文标题】:How to return/forward an observable inside Observable.create (RxSwift) 【发布时间】:2018-03-14 16:38:06 【问题描述】:

我想知道向我创建的 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

【问题讨论】:

【参考方案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 变成Observable,check here。

以上是关于如何在 Observable.create (RxSwift) 中返回/转发一个 observable的主要内容,如果未能解决你的问题,请参考以下文章

rx.js Observable 剖析(创建,订阅,执行,清理 )

如何在 Observable.create (RxSwift) 中返回/转发一个 observable

Angular项目中的Rxjs websockets

异步流与响应式扩展相比如何?

rxjs 5 发布重播引用计数

RxJava Observable.create 包装可观察订阅