web-dev-qa-db-ja.com

subscribeOnとobserveOnの順序は重要ですか?

オブザーバブルでsubscribeOnおよびobserveOnメソッドを呼び出すことができる順序について少し混乱しています。私は2、3の投稿を読みましたが、1人の男はそれは問題ではないと言っており、彼の例では単に物事を使用しています。だからここに私の質問があります:

例えば:

self.remoteService.rxGetAllLanguages()
            .observeOn(MainScheduler.instance)
            .subscribeOn(ConcurrentDispatchQueueScheduler(globalConcurrentQueueQOS: .Background))
            .subscribe({ e in
                switch e {
                case .Next(let element):

                case .Error(let e):
                    DDLogError("Error in  \(e)")
                case .Completed:
                    DDLogDebug("Completed")
                }
                }
            ).addDisposableTo(self.disposeBag)

それは同じです:

  self.remoteService.rxGetAllLanguages()
                    .subscribeOn(ConcurrentDispatchQueueScheduler(globalConcurrentQueueQOS: .Background))
                    .observeOn(MainScheduler.instance)
                    .subscribe({ e in
                        switch e {
                        case .Next(let element):

                        case .Error(let e):
                            DDLogError("Error in  \(e)")
                        case .Completed:
                            DDLogDebug("Completed")
                        }
                        }
                    ).addDisposableTo(self.disposeBag)

メカニズムを正しく理解していれば、それらは異なります。 1つ目はメインスレッドですべての作業を行い、2つ目は別のスレッドですべての作業を行ってから、メインスレッドにディスパッチします。しかし、私は確信しているので、誰かがこれをクリアしてくれますか?

30
user1007522

チェーンのどこでsubscribeOn()を呼び出すかは重要ではありません。 observeOn()を呼び出す場所は重要です。

subscribeOn()は、チェーン全体にstartの処理の対象となるスレッドを通知します。チェーンごとに1回だけ呼び出す必要があります。再びそれを下流に呼び出しても、効果はありません。

observeOn()その下で発生するすべての操作が、指定されたスケジューラで実行されます。ストリームごとに複数回呼び出して、異なるスレッド間を移動できます。

次の例を見てください。

doSomethingRx()
    .subscribeOn(BackgroundScheduler)
    .doAnotherThing()
    .observeOn(ComputationScheduler)
    .doSomethingElse()
    .observeOn(MainScheduler)
    .subscribe(//...)
  • subscribeOnにより、BackgroundSchedulerでdoSomethingRxが呼び出されます。
  • doAnotherThingはBackgroundSchedulerで続行されます
  • 次にobserveOnはストリームをComputationSchedulerに切り替えます
  • doSomethingElseはComputationSchedulerで発生します
  • 別のobserveOnは、ストリームをMainSchedulerに切り替えます
  • 購読はMainSchedulerで行われます
58
Jahnold

.subscribeOn()演算子は、作成されるShedulerチェーン(その左側に)に影響を与え、1回だけ機能します。 .observeOn()はその右側の演算子に影響を与えます-演算子の後にスケジューラデータが処理されます。

1
Alex Shutov

ええ、あなたは正しいです。 observeOnは指定したスレッドのイベントのみを受信しますが、subscribeOnは実際には指定したスレッド内で作業を実行します。

1
solidcell