2016-10-20 32 views
10

Bu, temel olarak bir RxJ en iyi uygulama/yaklaşım sorusudur, çünkü POC kodum çalışır, ancak RxJ'lerde yeniyim.RxJS - .subscribe() vs .publish(). Connect()

.subscribe() vs .publish().connect() sorusuna benzer, çünkü ikisi de aynı şeyi yapıyor gibi görünüyor.

Angular2 uygulamamda, kullanıcının oturumunu kapatmak için bir işlevi çağıran bir düğmem var; bu, bazı sunucu tarafı eylemlerini gerçekleştiren ve kullanıcının yönlendirmesi için bana bir URL gönderen bir işlevi çağırıyor. İsteği başlatmak için gözlemlenebilir değerlerin üretmeye başlaması için .subscribe() numaralı telefonu arayın. "Cold vs Hot Observables" ile ilgili bir yazı okuyordum ve başka bir yaklaşım ise .subscribe() yerine .publish().connect()'u aramak olurdu. Yaklaşmak için herhangi bir yarar var mı?

<a (click)="logout()">Logout</a> 

çıkış fonksiyonu şuna benzer: Böyle

logout.component.ts

logout() { this.authService.logout(); } 

Ve hizmet (gerçek çıkış) görünür:

auth. service.ts

logout() : Observable<boolean> { 
     this.http.get(this.location.prepareExternalUrl('api/v1/authentication/logout')) 
      .map(this.extractData) 
      .catch(this.handleError) 
      .do((x: string) => { window.location.href = x; }) 
      .subscribe(); // Option A - 

     return Observable.of(true); 

    } 

auth.service.alternative.ts

logout() : Observable<boolean> { 
     this.http.get(this.location.prepareExternalUrl('api/v1/authentication/logout')) 
      .map(this.extractData) 
      .catch(this.handleError) 
      .do((x: string) => { window.location.href = x; }) 
      .publish() // Option B - Make connectable observable 
      .connect(); // Option B - Cause the connectable observable to subscribe and produce my value  

     return Observable.of(true); 
    } 

cevap

12

subscribe() ve .publish().connect() arasındaki fark gözlemlenebilir kaynağına abone olduğunuzda içindedir. Aşağıdaki gözlemlenebilir düşünün:

let source = Observable.from([1, 2, 3]) 

Bu gözlemlenebilir yaydığı tüm değerleri bir Observer için bu abone doğru zaman.Sonra iki Gözlemcilerini varsa yüzden sırayla tüm değerleri alırsınız:

Bu konsola yazdırır
source.subscribe(val => console.log('obs1', val)); 
source.subscribe(val => console.log('obs2', val)); 

: .publish() arayarak Öte yandan

obs1 1 
obs1 2 
obs1 3 
obs2 1 
obs2 2 
obs2 3 

bir ConnectableObservable döndürür. Bu Gözlemlenebilir, yapıcısına onun kaynağına (örneğimizdeki source) abone değildir ve sadece referansını saklar. Sonra birden fazla Gözlemciye abone olabilirsiniz ve hiçbir şey olmuyor. Son olarak, source numarasına connect() ve ConnectableObservable abonelerini çağırarak, çıkış değerlerini başlatırsınız. yazdırır

let connectable = source.publish(); 
connectable.subscribe(val => console.log('obs1', val)); 
connectable.subscribe(val => console.log('obs2', val)); 
connectable.connect(); 

konsola:

obs1 1 
obs2 1 
obs1 2 
obs2 2 
obs1 3 
obs2 3 

Bkz canlı demo: Bu kez şimdiden iki Gözlemcilerini yüzden tek Bunlardan biri her iki değerleri yayar abone oradayız http://plnkr.co/edit/ySWocRr99m1WXwsOGfjS?p=preview

+0

Benim durumumda, sadece gözle görülür bir şekilde hemen yürütmeyi istediğim yerde, .subscribe() işlevini hiçbir argüman olmadan çağırmak, muhtemelen bunu gerçekleştirmenin en özlü yolu ve .publish(). connect() 'dir. bunu dolambaçlı bir şekilde gerçekleştirir. – ClaytonK

+1

@ClaytonK Genel olarak evet, çoğu zaman subscribe() 'yeterlidir. – martin

+0

Çıkış siparişi neden değişiyor? Her iki örnekte, 'obs2' nin abone olma ikincisi olduğunu gösteriyor? .share() 'gibi mi? –

3

Bu sorunuzu biraz sidesteps ama bunu size yardımcı olabilir:

Ben farklı bir gözlemlenebilir akışı dönmeyeceğini http hizmetini çağırır, bu nedenle arama işlevi için imkansız kılar:

  • Akışı iptal et
  • yerine

yapardım operasyon başarılı olup olmadığını

  • belirlemek akışı değiştirin:

    auth.servive.ts

    logout() : Observable<string> { 
         return this.http.get(...).map(this.extractData)   
          .catch(this.handleError); 
    } 
    

    Şimdi çağıran kod can sonuçta ortaya çıkan url ile ne yaparsa yapın

    logout.component.ts

    logout(){ 
        this.authService.logout().subscribe(
         url => window.location.href = url, 
         err => { 
          /*todo: handle if error was thrown by authService.handleError*/ 
         } 
        ); 
    } 
    
  • +0

    takdir edit @HarryNinh – BeetleJuice