2016-06-22 18 views
16

Jestem trochę zdezorientowany, jeśli chodzi o zlecenie, które można nazwać metodami subscribeOn i observeOn w obserwatorach. Przeczytałem kilka postów i jeden facet mówi, że to nie ma znaczenia i po prostu używa rzeczy w swoim przykładzie, a inni mówią, że to ma znaczenie. Więc tutaj jest moje pytanie:Czy kolejność subskrybowania i obserwowania ma znaczenie?

Na przykład:

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) 

Czy to tak samo jak:

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) 

Gdybym poprawnie zrozumieć mechanizmy są one różne. Pierwszy wykonuje całą pracę nad głównym wątkiem, a drugi wykonuje całą pracę nad innym wątkiem, a następnie przesyła z powrotem do głównego wątku. Ale jestem pewien, czy ktoś może to dla mnie wyjaśnić?

Odpowiedz

31

Tam, gdzie wywołujesz subscribeOn() w łańcuchu, nie ma to znaczenia. Gdzie dzwonisz pod numer observeOn() ma znaczenie.

subscribeOn() mówi cały łańcuch, który wątku początku przetwarza dalej. Powinieneś go nazwać tylko raz na każdy łańcuch. Jeśli zadzwonisz ponownie w dół strumienia, nie będzie to miało żadnego efektu.

observeOn() powoduje, że wszystkie operacje wykonywane poniżej są wykonywane na określonym harmonogramie. Możesz wywoływać go kilka razy na strumień, aby przechodzić między różnymi wątkami.

Weźmy następujący przykład:

doSomethingRx() 
    .subscribeOn(BackgroundScheduler) 
    .doAnotherThing() 
    .observeOn(ComputationScheduler) 
    .doSomethingElse() 
    .observeOn(MainScheduler) 
    .subscribe(//...) 
  • The subscribeOn przyczyn doSomethingRx się nazywać na BackgroundScheduler.
  • doAnotherThing będzie nadal na BackgroundScheduler
  • następnie observeOn przełącza strumień do ComputationScheduler
  • doSomethingElse nastąpi na ComputationScheduler
  • inny observeOn przełącza strumień do MainScheduler
  • subskrybowania dzieje się na MainScheduler
+0

Witam @Jahnold, dokumentacja RxSwift mówi: "Jeśli chcesz rozpocząć generowanie sekwencji (metoda subskrypcji) i wywołać utylizację określonego programu planującego, użyj funkcji subscribeOn (scheduler)." Czy to oznacza, że ​​jeśli określimy subscribeOn (:), uruchomi on łańcuch określony na podanym wątku, także dispos disposable zostanie wywołany na tym samym określonym wątku? – iamyogish

0

Tak, masz rację. observeOn będzie otrzymywać zdarzenia tylko w określonym przez ciebie wątku, natomiast subscribeOn wykona pracę w określonym wątku.

0

.subscribeOn() wpływa na operator, na którym zostanie utworzony łańcuch sheduler (w lewo z tego) i działa raz. .observeOn() wpływa na operatora na prawo od niego - na którym dane schedulerów będą przetwarzane po operatorze.

Powiązane problemy