连接两个都有subscribeOn的可观察序列。如何确保我的observable在线程上运行?

时间:2017-02-07 09:43:26

标签: swift rx-swift

当强制要求某个Observable.create代码在特定线程(即后台线程)中运行时,我担心使用subscribeOn运算符可能不起作用,因为有时候我可能会将此可观察序列链接到另一个在主线程上运行的可观察序列(使用observeOn)。

实施例

情况是我在主线程上运行了一个Observable序列(即一个警告框询问用户输入,是否执行网络调用)。

通过以下方式确保此Observable.create代码在后台线程中运行会更好吗

Observable<String>.empty()
   .observeOn(ConcurrentMainScheduler(queue: background.queue))
   .concat(myObservableNetworkCall)

为什么不使用subscribeOn

问题是如果我使用subscribeOn(第二个)并且先前的observable(警报控制器)设置为使用subscribeOn(第一个)在后台线程上运行,那么第二个{{ 1}}运算符无法工作,因为第一次调用更靠近源可观察量:

  

如果指定多个subscribeOn()运算符,那么将关闭源(最左侧),将使用的那个。

     

这可能是RxJava的行为,但我不确定Swift。 Reactivex.io只是说我们不应多次调用subscribeOn

我倾向于将操作包装到subscribeOn中,并且它们需要在不同的线程上运行...这就是为什么我要求如何确保在我指定的线程中运行Observable代码。 Observable<Void>不起作用,因为我可以连接observable。

我希望它应该运行的线程被封装在我的Observable定义中,而不是在链中更高的位置。

执行以下操作是最佳做法:

  1. 使用我想要使用的数据类型开始使用Observable.empty。
  2. 使用subscribeOn强制运行我希望它运行的线程。
  3. 将它与我想要使用的实际Observable连接。
  4. 修改

    1. 我已阅读有关reactivex.io的observeOnsubscribeOn文档。

    2. 我熟悉如何使用observeOnsubscribeOn在线程之间切换。

    3. 我特别关注的是在连接或组合可观察序列时使用observeOn的复杂性。

    4. 问题是,观察者需要专门在一个线程上运行,并且他们不知道他们将在哪里以及与谁联系。由于我确切地知道它们应该运行哪个线程,所以我更愿意将调度程序定义封装在observable的定义中,而不是在我链接序列时。

1 个答案:

答案 0 :(得分:0)

在函数声明中,最好不要指定调用函数的线程。 例如:

func myObservableNetworkCall() -> Observable<String> {
    return Observable<String>.create { observer in
        // your network code here

        return Disposables.create {
            // Your dispose
        }
    }
}

func otherObservableNetworkCall(s: String) -> Observable<String> {
    return Observable<String>.create { observer in
        // your network code here

        return Disposables.create {
            // Your dispose
        }
    }
}

然后在调度程序之间切换:

myObservableNetworkCall()
    .observeOn(ConcurrentMainScheduler(queue: background.queue)) // .background thread, network request, mapping, etc...
    .flatMap { string in
        otherObservableNetworkCall(s: string)
    }
    .observeOn(MainScheduler.instance) // switch to MainScheduler, UI updates
    .subscribe(onNext:{ string in
        // do something 
    })