2017-07-26 20 views
6

Açısal ve RxJ'ler konusundaki anlayışımdan Gözlemcileri sonlandırmak için iki yol vardır. Onlardan unsubscribe() yapabilir veya takeUntil() ve complete()'u kullanabilirsiniz. Aşağıda her yaklaşımın örnekleridir (sözde kodda).Açısal - Gözlemleri sonlandırmak için tercih edilen yol nedir?

abonelikten() yaklaşımı

private _id: number; 
private _subscriptions: Subscription[] = []; 

constructor(private _route: ActivatedRoute) { 
    this._getId(); 
} 

public ngOnDestroy(): void { 
    this._subscriptions.forEach(
     subscription => subscription.unsubscribe() 
    ); 
} 

private _getId(): void { 
    this._subscriptions.push(
     this._route.params.subscribe(params => this._id = +params['id']) 
    ); 
} 

takeUntil() ve tam() yaklaşımı Açısal olarak

private _id: number; 
private _ngUnsubscribe: Subject<void> = new Subject<void>(); 

constructor(private _route: ActivatedRoute) { 
    this._getId(); 
} 

public ngOnDestroy(): void { 
    this._ngUnsubscribe.next(); 
    this._ngUnsubscribe.complete(); 
} 

private _getId(): void { 
    this._route.params.takeUntil(this._ngUnsubscribe).subscribe(
     params => this._id = +params['id'] 
    ); 
} 

, gözlenebilirler sonlandırmak için tercih edilen bir yol var?

+2

tercih edilen bir yol yapıyorsun ngOnDestroy', 'içindedir. Ekleyebileceğim tek şey, değerlerin "doğruluk" değil, null ya da undefined olmamasıdır, aksi takdirde "abonelikten çık()" demeye çalışmak için bir hata alırsınız. – Lansana

+1

Ve sık sık örnekte yönlendirici parametreleri gibi ortak gözlenebilirleri sonlandırmanıza gerek olmadığını unutmayın. Açısal onları otomatik olarak sonlandırır. Dokümanların bu bölümünün altındaki notlara bakın: https://angular.io/guide/router#activatedroute-the-one-stop-shop-for-route-information – DeborahK

+1

[bu cevap] 'a bakın (https://stackoverflow.com/a/41177163/2545680) –

cevap

4

Her iki yaklaşım da eşdeğeri olmamasına rağmen doğrudur.

unsubscribe() kullanarak benim görüşüme göre (ve deneyim) genellikle daha fazla anlam ifade eder ve RxJS ile ilgili kapsamlı deneyime sahip olmayan diğer geliştiriciler için daha açıktır.

takeUntil()'u kullanmak, RxJS 5 (https://medium.com/@benlesh/rxjs-dont-unsubscribe-6753ed4fda87) ürününün geliştiricisi tarafından önerilir ve bazen birden fazla abonelik nesnesinin kullanılmasından daha kolaydır. Örneğin, bir akışı ikiye bölmek için partition() operatörünü kullanırsanız, yalnızca takeUntil(...).partition(...)'u kullanmak daha kolaydır.

Bu iki
  1. aynı değildir:

    Ancak iki önemli şey vardır. Eğer takeUntil() kullanırsanız, Gözlemlenebilir zinciri tamamlıyorsunuz demektir, bu da tüm tüm tutamaçların çağrıldığını ve ardından yırtılma fonksiyonlarının izlendiği anlamına gelir. Diğer yandan, unsubscribe()'u aradığınızda sadece yırtılarak işlevler çağrılır (finally() gibi operatörler dahil).

    Bu yüzden, unsubscribe()'u kullanmanın daha mantıklı olduğunu düşünüyorum. takeUntil() ile, sadece aboneliğinizi iptal etmek istediğiniz halde (completecomplete sinyali ile çalışan operatörlerin yeniden abone olabilmesini sağlayan repeat() sinyalini bildirerek) çalıştırılan bir complete işleyicisine sahip olabilirsiniz. Abonelikten çıkmak istediğiniz gerçek, Gözlemlenebilir kaynağın tamamlandığı anlamına gelmez. Değerleri hakkında artık bir şey umursamıyorsunuz, bu nedenle bu durumda unsubscribe()'u kullanmak daha iyi olacaktır. Bununla birlikte, pratikte, zinciri tamamladığınızdan veya sadece aboneliğinizi iptal edip etmediğiniz genellikle fark etmez.

  2. Tek bir birine Subscription s oluşturmak ve tek seferde hepsini abonelikten çıkabilirsiniz:

    const subscription = new Subscription(); 
    
    const sub1 = Observable...subscribe(...); 
    const sub2 = Observable...subscribe(...); 
    const sub3 = Observable...subscribe(...); 
    
    subscription.add(sub1).add(sub2).add(sub3); 
    
    ... 
    
    subscription.unsubscribe(); // unsubscribes all of them 
    
0

Bunu yapmamın yolu, Gözlemlenebilirse ilk olarak ngOnDestroy numaralı telefonu denetlemektir. Evet ise, o zaman aboneliğinizi iptal edin. Aşağıda, uygulamamın kod snippet'i var.

accountSubscriptionObj : Subscription; 

ngOnDestroy() { 
    if (this.accountSubscriptionObj) { 
     this.accountSubscriptionObj.unsubscribe(); 
    } 
    } 

Bu arada, zaman uyumsuz borusu, @HostListener, Gözlenebilen Sonlu çıkmak gerekmez. Bileşen yok olduğunda, olası bellek sızıntılarını önlemek için async borusu otomatik olarak aboneliği iptal eder. Sonlu bir sıraya sahip olduğunuzda, örneğin, HTTP hizmetini veya gözlemlenebilir zamanlayıcıyı kullanırken, genellikle aboneliğinizi iptal etmeniz gerekmez. Daha fazla referans için read here.

İlgili konular