--- Düzenleme 4 - Ek Kaynaklar (2018/09/01)
Açısal Ben Lesh ve Ward Bell'deki Adventures'ın son bir bölümünde, bir bileşende nasıl / ne zaman abonelikten çıkılacağı konuları tartışılıyor. Tartışma yaklaşık 1:05:30 'da başlıyor.
Ward right now there's an awful takeUntil dance that takes a lot of machineryve Shai Reznik'den bahseder Angular handles some of the subscriptions like http and routing.
Yanıt olarak Ben, şu anda Gözlemlenebilirlerin Açısal bileşen yaşam döngüsü olaylarına bağlanmasına izin vermek için tartışmalardan bahsetmektedir ve Ward, bir bileşenin bileşen iç durumu olarak tutulan Gözlemlenebilirlerin ne zaman tamamlanacağını bilmenin bir yolu olarak abone olabileceği bir Gözlemlenebilir yaşam döngüsü olayları önermektedir.
Bununla birlikte, şimdi çoğunlukla çözümlere ihtiyacımız var, işte başka kaynaklar.
takeUntil()RxJs çekirdek ekip üyesi Nicholas Jamieson'dan desen için bir öneri ve onu uygulamaya yardımcı olacak bir tslint kuralı. https://ncjamieson.com/avoiding-takeuntil-leaks/
Bileşen örneğini ( this) parametre olarak alan ve sırasında aboneliği otomatik olarak iptal eden Gözlemlenebilir bir işlecin bulunduğu Hafif npm paketi ngOnDestroy.
https://github.com/NetanelBasal/ngx-take-until-destroy
AOT yapıları yapmıyorsanız, yukarıdakilerin biraz daha iyi ergonomi ile başka bir varyasyonu (ancak şimdi hepimiz AOT yapıyor olmalıyız).
https://github.com/smnbbrv/ngx-rx-collector
*ngSubscribeEşzamansız boru gibi çalışan ancak şablonunuzda gömülü bir görünüm oluşturan özel yönerge , böylece şablonunuzdaki 'paketlenmemiş' değere başvurabilirsiniz.
https://netbasal.com/diy-subscription-handling-directive-in-angular-c8f6e762697f
Nicholas'ın bloguna yaptığı bir açıklamada, aşırı kullanımının, takeUntil()bileşeninizin çok fazla yapmaya çalıştığının ve mevcut bileşenlerinizi Özellik ve Sunum bileşenlerine ayırmanın dikkate alınması gerektiğinin bir işareti olabileceğinden bahsediyorum . Daha sonra | async, Özellik bileşeninden Gözlemlenebilir bileşeninin bir InputSunum bileşenine dönüştürülebilir, bu da hiçbir yerde abonelik gerekmediği anlamına gelir. Bu yaklaşım hakkında daha fazla bilgiyi buradan edinebilirsiniz
--- Düzenleme 3 - 'Resmi' Çözüm (2017/04/09)
Ward Bell ile NGConf'taki bu soru hakkında konuştum (ona doğru olduğunu söylediği bu cevabı bile gösterdim) ama bana Angular için dokümanlar ekibinin yayınlanmamış bu soruya bir çözümü olduğunu söyledi (onaylanmaya çalışsalar da) ). Ayrıca SO cevabımı önümüzdeki resmi tavsiyeyle güncelleyebileceğimi söyledi.
İleriye doğru kullanmamız gereken çözüm , sınıf kodlarında çağrıları olan private ngUnsubscribe = new Subject();tüm bileşenlere bir alan eklemektir ..subscribe()Observable
Sonra diyoruz this.ngUnsubscribe.next(); this.ngUnsubscribe.complete();bizim de ngOnDestroy()yöntemlerle.
Gizli sos ( @metamaker tarafından zaten belirtildiği gibi ), bileşenlerin yok edildiğinde tüm aboneliklerin temizleneceğini garanti edecek takeUntil(this.ngUnsubscribe)her çağrıdan önce aramaktır.subscribe() .
Misal:
import { Component, OnDestroy, OnInit } from '@angular/core';
// RxJs 6.x+ import paths
import { filter, startWith, takeUntil } from 'rxjs/operators';
import { Subject } from 'rxjs';
import { BookService } from '../books.service';
@Component({
selector: 'app-books',
templateUrl: './books.component.html'
})
export class BooksComponent implements OnDestroy, OnInit {
private ngUnsubscribe = new Subject();
constructor(private booksService: BookService) { }
ngOnInit() {
this.booksService.getBooks()
.pipe(
startWith([]),
filter(books => books.length > 0),
takeUntil(this.ngUnsubscribe)
)
.subscribe(books => console.log(books));
this.booksService.getArchivedBooks()
.pipe(takeUntil(this.ngUnsubscribe))
.subscribe(archivedBooks => console.log(archivedBooks));
}
ngOnDestroy() {
this.ngUnsubscribe.next();
this.ngUnsubscribe.complete();
}
}
Not:takeUntil Operatör zincirindeki ara gözlemlenebilir sızıntıları önlemek için operatörü sonuncusu olarak eklemek önemlidir .
--- Düzenleme 2 (2016/12/28)
Kaynak 5
Açısal öğretici, Yönlendirme bölümünde şu şekilde belirtilmektedir: "Yönlendirici sağladığı gözlemlenebilirleri yönetir ve abonelikleri yerelleştirir. Bileşen imha edildiğinde abonelikler temizlenir, bellek sızıntılarına karşı korunur, Güzergah gözlemlenebilir. " - Mark Rajcok
Ward Bell'in tüm bunlara ilişkin açıklamaların eserlerde yer aldığı Yönlendirici Gözlemlerle ilgili Açısal dokümanlar için Github sorunları üzerine bir tartışma .
--- Düzenleme 1
Kaynak 4
NgEurope Rob Wormald'ın bu videosunda Router Observables aboneliğini iptal etmenize gerek olmadığını söylüyor. Ayrıca httphizmetten ve Kasım 2016'danActivatedRoute.params bu videoda bahsediyor .
--- Orijinal Yanıt
TLDR:
Bu soru için (2) türü vardır Observables- sonlu değer ve sonsuz değere.
http Observablessonlu (1) değerler üretir ve DOM gibi bir şey sonsuz değerler event listener Observablesüretir .
El ararsanız subscribe, o zaman (zaman uyumsuz borusunu kullanarak değil) unsubscribedan sonsuzun Observables .
Sonlu olanlar için endişelenme RxJs, onlara bakacak.
Kaynak 1
Ben açısal en Gitter Rob Wormald bir cevap izini burada .
(Açıklık için yeniden düzenledim ve vurgu benim)
Bunu ise tek değerli bir bileşen (bir http isteği gibi) el temizleme gereksizdir (el ile kontrol cihazı abone varsayılarak)
i " tamamlayan bir sekans " demeliyim (tek değer sekansları, bir la http, bir olan)
onun sonsuz dizisi ise , abonelikten gereken zaman uyumsuz boru sizin için yapar hangi
Ayrıca bu youtube videosunda Observables hakkında they clean up after themselves... completeher zaman 1 değer ürettikleri ve bitirdikleri için her zaman tamamlanan Promises gibi - xhrolayı temizlediklerinden emin olmak için Promises'tan abonelikten çıkma konusunda asla endişelenmedik dinleyiciler, değil mi?).
Kaynak 2
Ayrıca açısal 2'ye Rangle rehber okur
Çoğu durumda, erken iptal etmek istemedikçe veya Gözlemlenebilirlik aboneliğimizden daha uzun bir ömre sahip olmadıkça, abonelikten çıkma yöntemini açıkça çağırmamız gerekmeyecektir. Gözlemlenebilir işleçlerin varsayılan davranışı, .complete () veya .error () iletileri yayımlanır yayınlanmaz aboneliği atmaktır. RxJS'nin çoğu zaman "ateşle ve unut" tarzında kullanılmak üzere tasarlandığını unutmayın.
İfade ne zaman our Observable has a longer lifespan than our subscriptionuygulanır?
ObservableTamamlanma işleminden önce (veya çok önce değil) yok edilen bir bileşenin içinde bir abonelik oluşturulduğunda geçerlidir .
Bunu bir değer httpveya 10 değer yayan bir gözlemlenebilirliğe abone olursak ve bu httpistek geri gelmeden ya da 10 değer gönderilmeden önce bileşenimiz yok edilirse anlam olarak okudum , hala iyiyiz!
İstek geri döndüğünde veya 10. değer sonunda verildiğinde, istek Observabletamamlanır ve tüm kaynaklar temizlenir.
Kaynak 3
Biz bakarsak bu örnekte aynı Rangle biz görebilirsiniz rehberlik Subscriptionetmek route.paramsbir gerektirir unsubscribe()olanlar ne zaman biz bilmiyoruz çünkü paramsdeğişen (yeni değerler yayan) duracaktır.
Bileşen uzaklaşarak yok edilebilir, bu durumda rota parametreleri muhtemelen değişecektir (uygulama sona erene kadar teknik olarak değişebilirler) ve a olmadığı için abonelikte ayrılan kaynaklar yine tahsis edilecektir completion.
Subscriptionüzere shttp-requestsonlar sadece dediğimiz gibi göz ardı edilebilironNextbir kez ve sonra da diyoruzonComplete. BununRouteryerineonNexttekrar tekrar çağırır ve asla çağıramazonComplete(bundan emin değilsiniz ...). Aynı şeyObservables'denEvents için de geçerlidir. Yani sanırım bunlar olmalıunsubscribed.