--- 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 machinery
ve 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
*ngSubscribe
Eş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 Input
Sunum 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 http
hizmetten 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
Observables
sonlu (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) unsubscribe
dan 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
... complete
her zaman 1 değer ürettikleri ve bitirdikleri için her zaman tamamlanan Promises gibi - xhr
olayı 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 subscription
uygulanır?
Observable
Tamamlanma 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 http
veya 10 değer yayan bir gözlemlenebilirliğe abone olursak ve bu http
istek 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 Observable
tamamlanır ve tüm kaynaklar temizlenir.
Kaynak 3
Biz bakarsak bu örnekte aynı Rangle biz görebilirsiniz rehberlik Subscription
etmek route.params
bir gerektirir unsubscribe()
olanlar ne zaman biz bilmiyoruz çünkü params
değ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-requests
onlar sadece dediğimiz gibi göz ardı edilebilironNext
bir kez ve sonra da diyoruzonComplete
. BununRouter
yerineonNext
tekrar tekrar çağırır ve asla çağıramazonComplete
(bundan emin değilsiniz ...). Aynı şeyObservable
s'denEvent
s için de geçerlidir. Yani sanırım bunlar olmalıunsubscribed
.