2016-06-22 8 views
16

Sono un po 'confuso circa l'ordine è possibile chiamare i metodi subscribeOn e observeOn su osservabili. Ho letto un paio di post e un tizio dice che non ha importanza e usa solo le cose nel suo esempio e altre persone dicono che è importante. Quindi ecco la mia domanda:L'ordine di subscribeOn e observOn importa?

Ad esempio:

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) 

è che lo stesso come:

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) 

Se ho capito bene i meccanismi sono diversi. Il primo esegue tutto il lavoro sul thread principale e il secondo esegue tutto il lavoro su un altro thread e quindi torna al thread principale. Ma sono sicuro che sia così qualcuno può chiarirlo per me, per favore?

risposta

31

Dove si chiama subscribeOn() in una catena non importa. Dove si chiama observeOn() importa.

subscribeOn() dice tutta la catena che filo inizio di elaborazione su. Dovresti chiamarlo solo una volta per catena. Se lo chiami di nuovo più in basso, il flusso non avrà alcun effetto.

observOn() fa sì che tutte le operazioni che si verificano al di sotto di esso siano eseguite sullo scheduler specificato. Puoi chiamarlo più volte per flusso per spostarti tra diversi thread.

Prendiamo il seguente esempio:

doSomethingRx() 
    .subscribeOn(BackgroundScheduler) 
    .doAnotherThing() 
    .observeOn(ComputationScheduler) 
    .doSomethingElse() 
    .observeOn(MainScheduler) 
    .subscribe(//...) 
  • Le cause subscribeOndoSomethingRx di essere chiamato sul BackgroundScheduler.
  • doAnotherThing proseguirà BackgroundScheduler
  • quindi observeOn passa il flusso lungo la ComputationScheduler
  • doSomethingElse accadrà sul ComputationScheduler
  • un'altra observeOn passa il flusso lungo la MainScheduler
  • sottoscrivi avviene sulla MainScheduler
+0

Hi @Jahnold, la documentazione RxSwift dice: "Se si desidera avviare la generazione della sequenza (metodo subscribe) e chiamare lo smaltimento su uno schedulatore specifico, utilizzare subscribeOn (scheduler)." Questo significa che se si specifica subscribeOn (:), avvierà la catena su specificato nel thread specificato, anche lo smaltimento del disposable sarà chiamato sullo stesso thread specificato? – iamyogish

0

Sì, hai ragione. observeOn riceverà gli eventi solo sulla discussione che hai specificato, mentre subscribeOn eseguirà effettivamente il lavoro all'interno del thread specificato.

0

.subscribeOn() influenza su cui verrà creata la catena di sheduler (a sinistra di esso) e funziona una volta. .observeOn() influenza l'operatore a destra di esso - su quali dati degli scheduler verranno elaborati dopo l'operatore.