Kapan saya harus menyimpan Subscription
instance dan memohon unsubscribe()
selama siklus hidup NgOnDestroy dan kapan saya bisa mengabaikannya?
Menyimpan semua langganan menimbulkan banyak kekacauan dalam kode komponen.
Panduan Klien HTTP mengabaikan langganan seperti ini:
getHeroes() {
this.heroService.getHeroes()
.subscribe(
heroes => this.heroes = heroes,
error => this.errorMessage = <any>error);
}
Pada saat yang sama Panduan Rute & Navigasi mengatakan bahwa:
Akhirnya, kami akan menavigasi ke tempat lain. Router akan menghapus komponen ini dari DOM dan menghancurkannya. Kita perlu membersihkan diri kita sendiri sebelum itu terjadi. Secara khusus, kita harus berhenti berlangganan sebelum Angular menghancurkan komponen. Kegagalan untuk melakukannya dapat membuat kebocoran memori.
Kami berhenti berlangganan dari kami
Observable
dingOnDestroy
metode.
private sub: any;
ngOnInit() {
this.sub = this.route.params.subscribe(params => {
let id = +params['id']; // (+) converts string 'id' to a number
this.service.getHero(id).then(hero => this.hero = hero);
});
}
ngOnDestroy() {
this.sub.unsubscribe();
}
angular
rxjs
observable
subscription
angular-component-life-cycle
Sergey Tihon
sumber
sumber
Subscription
shttp-requests
dapat diabaikan, karena mereka hanya memanggilonNext
sekali dan kemudian mereka memanggilonComplete
. TheRouter
bukan panggilanonNext
berulang-ulang dan mungkin tidak pernah memanggilonComplete
(tidak yakin tentang itu ...). Sama berlaku untukObservable
s dariEvent
s. Jadi saya kira itu seharusnyaunsubscribed
.subscribe
dirinya sendiri yang berpotensi mengalokasikan sumber daya hulu.Jawaban:
--- Sunting 4 - Sumber Daya Tambahan (2018/09/01)
Dalam episode baru-baru ini dari Adventures in Angular Ben Lesh dan Ward Bell membahas masalah seputar bagaimana / kapan harus berhenti berlangganan suatu komponen. Diskusi dimulai pada sekitar 1:05:30.
Ward menyebutkan
right now there's an awful takeUntil dance that takes a lot of machinery
dan Shai Reznik menyebutkanAngular handles some of the subscriptions like http and routing
.Sebagai tanggapan, Ben menyebutkan bahwa ada diskusi sekarang untuk memungkinkan Observable untuk terhubung ke peristiwa siklus hidup komponen Angular dan Ward menyarankan Observable peristiwa siklus hidup yang dapat berlangganan sebagai cara untuk mengetahui kapan harus menyelesaikan Observable yang dikelola sebagai keadaan internal komponen.
Yang mengatakan, kita sebagian besar membutuhkan solusi sekarang jadi di sini adalah beberapa sumber
Sebuah rekomendasi untuk
takeUntil()
pola dari anggota tim inti RxJs Nicholas Jamieson dan aturan tslint untuk membantu menegakkannya. https://ncjamieson.com/avoiding-takeuntil-leaks/Paket npm ringan yang mengekspos operator yang dapat diobservasi yang menggunakan instance komponen (
this
) sebagai parameter dan secara otomatis berhenti berlangganan selamangOnDestroy
. https://github.com/NetanelBasal/ngx-take-until-destroyVariasi lain di atas dengan ergonomi yang sedikit lebih baik jika Anda tidak melakukan build AOT (tetapi kita semua harus melakukan AOT sekarang). https://github.com/smnbbrv/ngx-rx-collector
Arahan khusus
*ngSubscribe
yang berfungsi seperti pipa async tetapi membuat tampilan tertanam di templat Anda sehingga Anda dapat merujuk ke nilai 'tidak terbuka' di seluruh templat Anda. https://netbasal.com/diy-subscription-handling-directive-in-angular-c8f6e762697fSaya menyebutkan dalam komentar di blog Nicholas bahwa penggunaan berlebihan
takeUntil()
bisa menjadi pertanda bahwa komponen Anda mencoba melakukan terlalu banyak dan bahwa memisahkan komponen yang ada menjadi komponen Fitur dan Presentasi harus dipertimbangkan. Anda kemudian dapat| async
diamati dari komponen Fitur keInput
dalam komponen Presentational, yang berarti tidak ada langganan yang diperlukan di mana pun. Baca lebih lanjut tentang pendekatan ini di sini--- Sunting 3 - Solusi 'Resmi' (2017/04/09)
Saya berbicara dengan Ward Bell tentang pertanyaan ini di NGConf (Saya bahkan menunjukkan kepadanya jawaban ini yang menurutnya benar) tetapi dia mengatakan kepada saya bahwa tim dokumen untuk Angular memiliki solusi untuk pertanyaan ini yang tidak dipublikasikan (walaupun mereka sedang berusaha untuk mendapatkan persetujuannya) ). Dia juga mengatakan kepada saya bahwa saya dapat memperbarui jawaban SO saya dengan rekomendasi resmi yang akan datang.
Solusi yang kita semua harus gunakan maju adalah menambahkan
private ngUnsubscribe = new Subject();
bidang ke semua komponen yang memiliki.subscribe()
panggilan keObservable
dalam kode kelas mereka.Kami kemudian memanggil metode
this.ngUnsubscribe.next(); this.ngUnsubscribe.complete();
kamingOnDestroy()
.Saus rahasia (sebagaimana telah dicatat oleh @metamaker ) adalah untuk menelepon
takeUntil(this.ngUnsubscribe)
sebelum masing-masing.subscribe()
panggilan kami yang akan menjamin semua langganan akan dibersihkan ketika komponen dihancurkan.Contoh:
Catatan: Penting untuk menambahkan
takeUntil
operator sebagai yang terakhir untuk mencegah kebocoran dengan yang dapat diamati antara dalam rantai operator.--- Edit 2 (2016/12/28)
Sumber 5
Tutorial Angular, bab Routing sekarang menyatakan sebagai berikut: "Router mengelola observable yang disediakan dan melokalisasi langganan. Langganan dibersihkan ketika komponen dihancurkan, melindungi terhadap kebocoran memori, jadi kita tidak perlu berhenti berlangganan dari rute params Teramati. " - Mark Rajcok
Berikut ini adalah diskusi tentang masalah Github untuk dokumen Angular mengenai Router Observables di mana Ward Bell menyebutkan bahwa klarifikasi untuk semua ini sedang dikerjakan.
--- Edit 1
Sumber 4
Dalam video ini dari NgEurope Rob Wormald juga mengatakan Anda tidak perlu berhenti berlangganan dari Router Observables. Dia juga menyebutkan
http
layanan danActivatedRoute.params
dalam video ini dari November 2016 .--- Jawaban Asli
TLDR:
Untuk pertanyaan ini ada (2) jenis
Observables
- nilai terbatas dan nilai tak terbatas .http
Observables
menghasilkan nilai hingga (1) dan sesuatu seperti DOMevent listener
Observables
menghasilkan nilai tak hingga .Jika Anda memanggil secara manual
subscribe
(tidak menggunakan pipa async), makaunsubscribe
dari infiniteObservables
.Jangan khawatir tentang yang terbatas ,
RxJs
akan mengurusnya.Sumber 1
Saya melacak jawaban dari Rob Wormald di Angular's Gitter di sini .
Dia menyatakan (saya mengatur ulang untuk kejelasan dan penekanan adalah milikku)
Dia juga menyebutkan dalam video youtube ini di Observables that
they clean up after themselves
... dalam konteks Observables yangcomplete
(seperti Janji, yang selalu lengkap karena mereka selalu menghasilkan 1 nilai dan berakhir - kami tidak pernah khawatir tentang berhenti berlangganan dari Janji untuk memastikan mereka membersihkanxhr
acara pendengar, kan?).Sumber 2
Juga di panduan Rangle ke Angular 2 berbunyi
Kapan frasa ini
our Observable has a longer lifespan than our subscription
berlaku?Ini berlaku ketika langganan dibuat di dalam komponen yang dihancurkan sebelum (atau tidak 'lama' sebelum)
Observable
selesai.Saya membaca ini sebagai makna jika kita berlangganan
http
permintaan atau yang dapat diamati yang memancarkan 10 nilai dan komponen kita dihancurkan sebelumhttp
permintaan itu kembali atau 10 nilai telah dipancarkan, kita masih ok!Ketika permintaan kembali atau nilai ke-10 akhirnya dikeluarkan
Observable
akan menyelesaikan dan semua sumber daya akan dibersihkan.Sumber 3
Jika kita melihat contoh ini dari panduan Rangle yang sama, kita dapat melihat bahwa
Subscription
toroute.params
tidak memerlukanunsubscribe()
karena kita tidak tahu kapan merekaparams
akan berhenti berubah (mengeluarkan nilai baru).Komponen dapat dihancurkan dengan menavigasi pergi dalam hal ini params rute kemungkinan masih akan berubah (mereka secara teknis bisa berubah sampai aplikasi berakhir) dan sumber daya yang dialokasikan dalam berlangganan masih akan dialokasikan karena belum ada
completion
.sumber
complete()
dengan sendirinya tampaknya tidak membersihkan langganan. Bagaimanapun panggilannext()
dan kemudiancomplete()
, saya percayatakeUntil()
hanya berhenti ketika nilai diproduksi, bukan ketika urutan berakhir.Subject
di dalam komponen dan beralih denganngIf
untuk memicungOnInit
danngOnDestroy
menunjukkan, bahwa subjek dan langganannya tidak akan pernah lengkap atau dibuang (terhubung denganfinally
operator ke langganan). Saya harus meneleponSubject.complete()
dingOnDestroy
, sehingga langganan dapat membersihkan diri mereka sendiri.takeUnitl
pendekatan ini, kami tidak pernah harus berhenti berlangganan secara manual dari yang terlihat? Apakah itu masalahnya? Selain itu, mengapa kita perlu panggilannext()
dingOnDestroy
, mengapa tidak hanya panggilancomplete()
?Anda tidak perlu memiliki banyak langganan dan berhenti berlangganan secara manual. Gunakan Subjek dan ambil Kombinasikan hingga untuk menangani langganan seperti bos:
Pendekatan alternatif , yang diusulkan oleh @acumartini dalam komentar , menggunakan takeWhile alih-alih takeUntil . Anda mungkin lebih menyukainya, tetapi ingatlah bahwa cara ini eksekusi Anda yang Teramati tidak akan dibatalkan pada ngDestroy komponen Anda (misalnya ketika Anda membuat perhitungan yang memakan waktu atau menunggu data dari server). Metode, yang didasarkan pada takeUntil , tidak memiliki kelemahan ini dan menyebabkan pembatalan permintaan segera. Terima kasih kepada @AlexChe untuk penjelasan terperinci dalam komentar .
Jadi inilah kodenya:
sumber
takeUntil
dantakeWhile
. Mantan berhenti berlangganan dari sumber diamati segera ketika dipecat, sedangkan yang terakhir berhenti berlangganan segera setelah nilai berikutnya dihasilkan oleh sumber diamati. Jika menghasilkan nilai oleh sumber yang dapat diamati adalah operasi yang memakan sumber daya, memilih di antara keduanya dapat melampaui preferensi gaya. Lihat bungkusan itutakeUntil
vstakeWhile
, bukan untuk kasus khusus kami. Ketika kita perlu berhenti berlangganan pendengar pada penghancuran komponen , kita hanya memeriksa nilai boolean seperti() => alive
dalamtakeWhile
, sehingga setiap operasi memakan waktu / memori tidak digunakan dan perbedaannya cukup banyak tentang styling (ofc, untuk kasus khusus ini).Observable
, yang secara internal menambang beberapa mata uang kripto dan membuatnext
acara untuk setiap koin yang ditambang, dan menambang satu koin semacam itu membutuhkan waktu sehari. DengantakeUntil
kami akan berhenti berlangganan dari penambangan sumberObservable
segera setelahngOnDestroy
dipanggil selama penghancuran komponen kami. Dengan demikianObservable
fungsi penambangan dapat membatalkan operasinya segera selama proses ini.takeWhile
, dingOnDestory
kita baru mengatur variabel boolean. TetapiObservable
fungsi penambangan mungkin masih berfungsi hingga satu hari, dan hanya selamanext
panggilan itu akan menyadari bahwa tidak ada langganan aktif dan perlu dibatalkan.Kelas Berlangganan memiliki fitur menarik:
Anda dapat membuat objek Berlangganan agregat yang mengelompokkan semua langganan Anda. Anda melakukan ini dengan membuat Langganan kosong dan menambahkan langganan ke dalamnya menggunakan
add()
metodenya. Ketika komponen Anda hancur, Anda hanya perlu berhenti berlangganan langganan agregat.sumber
takeUntil
pendekatan resmi versus pendekatan pengumpulan langganan dan panggilan iniunsubscribe
. (Pendekatan ini tampaknya jauh lebih bersih bagi saya.)this.subscriptions
itu nolsub = subsciption.add(..).add(..)
karena dalam banyak kasus ini menghasilkan hasil yang tidak terduga github.com/ReactiveX/rxjs/issues/2769#issuecomment-345636477Beberapa praktik terbaik terkait berhenti berlangganan yang dapat diamati di dalam komponen Angular:
Kutipan dari
Routing & Navigation
Dan dalam menanggapi tautan berikut:
http
diamatiSaya mengumpulkan beberapa praktik terbaik terkait berhenti berlangganan yang dapat diamati di dalam komponen Angular untuk dibagikan kepada Anda:
http
berhenti berlangganan yang dapat diamati adalah bersyarat dan kami harus mempertimbangkan efek dari 'berlangganan panggilan balik' dijalankan setelah komponen dihancurkan berdasarkan kasus per kasus. Kita tahu bahwa sudut berhenti berlangganan dan membersihkan yanghttp
dapat diamati itu sendiri (1) , (2) . Meskipun ini benar dari perspektif sumber daya, itu hanya menceritakan setengah dari cerita. Katakanlah kita berbicara tentang panggilan langsunghttp
dari dalam suatu komponen, danhttp
responsnya memakan waktu lebih lama dari yang dibutuhkan sehingga pengguna menutup komponen tersebut. Itusubscribe()
handler akan tetap dipanggil walaupun komponennya ditutup dan dihancurkan. Ini dapat memiliki efek samping yang tidak diinginkan dan dalam skenario yang lebih buruk membuat keadaan aplikasi rusak. Ini juga dapat menyebabkan pengecualian jika kode dalam panggilan balik mencoba memanggil sesuatu yang baru saja dibuang. Namun pada saat yang sama sesekali mereka diinginkan. Seperti, katakanlah Anda sedang membuat klien email dan Anda memicu suara ketika email selesai dikirim - yah Anda tetap ingin itu terjadi bahkan jika komponen ditutup ( 8 ).AsyncPipe
sebanyak mungkin karena secara otomatis berhenti berlangganan dari yang dapat diamati pada kerusakan komponen.ActivatedRoute
observable sepertiroute.params
jika mereka berlangganan di dalam bersarang (Ditambahkan dalam tpl dengan pemilih komponen) atau komponen dinamis karena mereka dapat berlangganan berkali-kali selama komponen induk / host ada. Tidak perlu berhenti berlangganan dari mereka dalam skenario lain seperti yang disebutkan dalam kutipan di atas dariRouting & Navigation
dokumen.Catatan: Mengenai layanan mencakup, yaitu penyedia komponen, mereka hancur ketika komponen dihancurkan. Dalam hal ini, jika kami berlangganan setiap yang dapat diamati di dalam penyedia ini, kami harus mempertimbangkan untuk berhenti berlangganan menggunakan
OnDestroy
kait siklus hidup yang akan dipanggil saat layanan dihancurkan, menurut dokumen.takeUntil
(3) atau Anda dapat menggunakannpm
paket ini di (4) Cara termudah untuk berhenti berlangganan dari Observables in Angular .FormGroup
diamati sepertiform.valueChanges
danform.statusChanges
Renderer2
sepertirenderer2.listen
HostListener
karena sudut peduli dengan baik tentang menghapus pendengar acara jika diperlukan dan mencegah kebocoran memori potensial karena ikatan acara.Kiat terakhir yang bagus : Jika Anda tidak tahu apakah ada pengamat yang secara otomatis berhenti berlangganan / selesai atau tidak, tambahkan
complete
panggilan balik kesubscribe(...)
dan periksa apakah itu dipanggil saat komponen dihancurkan.sumber
ngOnDestroy
disebut ketika layanan diberikan pada tingkat selain tingkat root misalnya disediakan secara eksplisit dalam komponen yang kemudian dihapus. Dalam kasus ini, Anda harus berhenti berlangganan dari layanan yang dapat diamatingOnDestroy
, yang selalu disebut ketika layanan dihancurkan github.com/angular/angular/commit/...Feel free to unsubscribe anyway. It is harmless and never a bad practice.
dan mengenai pertanyaan Anda, itu tergantung. Jika komponen anak diinisiasi beberapa kali (Misalnya, ditambahkan di dalamngIf
atau dimuat secara dinamis), Anda harus berhenti berlangganan untuk menghindari menambahkan beberapa langganan ke pengamat yang sama. Kalau tidak, tidak perlu. Tapi saya lebih suka berhenti berlangganan di dalam komponen anak karena ini membuatnya lebih dapat digunakan kembali dan terisolasi dari cara itu dapat digunakan.Tergantung. Jika dengan menelepon
someObservable.subscribe()
, Anda mulai menahan beberapa sumber daya yang harus dibebaskan secara manual ketika siklus hidup komponen Anda berakhir, maka Anda harus menelepontheSubscription.unsubscribe()
untuk mencegah kebocoran memori.Mari kita lihat lebih dekat contoh Anda:
getHero()
mengembalikan hasilhttp.get()
. Jika Anda melihat kode sumber sudut 2 ,http.get()
buat dua pendengar acara:dan dengan menelepon
unsubscribe()
, Anda dapat membatalkan permintaan serta pendengar:Perhatikan bahwa
_xhr
ini spesifik untuk platform tetapi saya pikir aman untuk menganggap bahwa ini adalahXMLHttpRequest()
untuk Anda.Biasanya, ini cukup bukti untuk menjamin
unsubscribe()
panggilan manual . Namun menurut spesifikasi WHATWG ini ,XMLHttpRequest()
pengumpulan sampah dapat dilakukan setelah selesai, bahkan jika ada pendengar acara yang terikat padanya. Jadi saya kira itu sebabnya panduan resmi sudut 2 tidak adaunsubscribe()
dan memungkinkan GC membersihkan pendengar.Adapun contoh kedua Anda, itu tergantung pada implementasi
params
. Sampai hari ini, panduan resmi sudut tidak lagi menunjukkan berhenti berlanggananparams
. Saya melihat ke src lagi dan menemukan ituparams
hanya sebuah BehaviorSubject . Karena tidak ada pendengar acara atau timer digunakan, dan tidak ada variabel global yang dibuat, itu harus aman untuk dihilangkanunsubscribe()
.Intinya untuk pertanyaan Anda adalah bahwa selalu memanggil
unsubscribe()
sebagai pelindung terhadap kebocoran memori, kecuali jika Anda yakin bahwa eksekusi yang diamati tidak menciptakan variabel global, menambahkan pendengar acara, mengatur penghitung waktu, atau melakukan hal lain yang menyebabkan kebocoran memori .Jika ragu, lihat implementasi yang dapat diamati. Jika observable telah menulis beberapa logika pembersihan ke dalamnya
unsubscribe()
, yang biasanya merupakan fungsi yang dikembalikan oleh konstruktor, maka Anda memiliki alasan yang baik untuk secara serius mempertimbangkan untuk memanggilunsubscribe()
.sumber
Dokumentasi resmi Angular 2 memberikan penjelasan kapan harus berhenti berlangganan dan kapan bisa diabaikan dengan aman. Lihat tautan ini:
https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service
Cari paragraf dengan tajuk Orang Tua dan anak-anak berkomunikasi melalui layanan dan kemudian kotak biru:
Saya harap ini membantu Anda.
sumber
Berdasarkan: Menggunakan pewarisan Kelas untuk menghubungkan ke siklus hidup komponen 2 Sudut
Pendekatan generik lain:
Dan gunakan:
sumber
this.componentDestroyed$.next()
panggilan seperti solusi yang diterima oleh sean di atas ...Jawaban Edit # 3 resmi (dan variasi) bekerja dengan baik, tetapi hal yang membuat saya adalah 'berlumpur' dari logika bisnis di sekitar langganan yang dapat diamati.
Berikut pendekatan lain menggunakan pembungkus.
File subscribeAndGuard.ts digunakan untuk membuat ekstensi yang bisa diamati baru untuk membungkus
.subscribe()
dan di dalamnya untuk membungkusngOnDestroy()
.Penggunaannya sama dengan
.subscribe()
, kecuali untuk parameter pertama tambahan yang mereferensikan komponen.Berikut adalah komponen dengan dua langganan, satu dengan pembungkus dan satu tanpa. Satu-satunya peringatan adalah ia harus mengimplementasikan OnDestroy (dengan tubuh kosong jika diinginkan), jika tidak, Angular tidak tahu untuk memanggil versi yang dibungkus.
Demo plunker ada di sini
Catatan tambahan: Re Edit 3 - Solusi 'Resmi', ini dapat disederhanakan dengan menggunakan takeWhile () alih-alih takeUntil () sebelum berlangganan, dan boolean sederhana dan bukan yang lain yang bisa diamati di ngOnDestroy.
sumber
Karena solusi seangwright (Edit 3) tampaknya sangat berguna, saya juga merasa kesulitan untuk mengemas fitur ini ke dalam komponen dasar, dan mengisyaratkan rekan tim proyek lain untuk mengingat untuk memanggil super () di ngOnDestroy untuk mengaktifkan fitur ini.
Jawaban ini memberikan cara untuk membebaskan dari panggilan super, dan menjadikan "componentDestroyed $" sebagai inti dari komponen dasar.
Dan kemudian Anda dapat menggunakan fitur ini secara bebas misalnya:
sumber
Mengikuti jawaban oleh @seangwright , saya telah menulis kelas abstrak yang menangani langganan yang dapat diamati "dalam komponen:
Untuk menggunakannya, cukup rentangkan di komponen sudut Anda dan panggil
subscribe()
metode berikut:Itu juga menerima kesalahan dan menyelesaikan panggilan balik seperti biasa, objek pengamat, atau tidak panggilan balik sama sekali. Ingatlah untuk menelepon
super.ngOnDestroy()
jika Anda juga menerapkan metode itu dalam komponen anak.Temukan di sini referensi tambahan oleh Ben Lesh: RxJS: Jangan Berhenti Berlangganan .
sumber
Saya mencoba solusi seangwright (Edit 3)
Itu tidak berfungsi untuk Observable yang dibuat oleh timer atau interval.
Namun, saya membuatnya bekerja dengan menggunakan pendekatan lain:
sumber
Aku seperti dua jawaban terakhir, tapi saya mengalami masalah jika subclass direferensikan
"this"
dingOnDestroy
.Saya memodifikasinya menjadi ini, dan sepertinya itu menyelesaikan masalah itu.
sumber
this.ngOnDestroy = () => { f.bind(this)(); this.componentDestroyed$.complete(); };
Dalam kasus berhenti berlangganan diperlukan operator berikut untuk metode pipa yang dapat diamati dapat digunakan
dapat digunakan seperti ini:
Operator membungkus metode komponen ngOnDestroy.
Penting: operator harus menjadi yang terakhir dalam pipa yang dapat diamati.
sumber
Anda biasanya harus berhenti berlangganan ketika komponen hancur, tetapi Angular akan menanganinya lebih dan lebih lagi seperti yang kita lakukan, misalnya dalam versi minor baru Angular4, mereka memiliki bagian ini untuk rute berhenti berlangganan:
Juga contoh di bawah ini adalah contoh yang baik dari Angular untuk membuat komponen dan menghancurkannya setelah, lihat bagaimana komponen mengimplementasikan OnDestroy, jika Anda membutuhkan onInit, Anda juga dapat mengimplementasikannya di komponen Anda, seperti mengimplementasikan
OnInit, OnDestroy
sumber
Tambahan pendek lain untuk situasi yang disebutkan di atas adalah:
sumber
dalam aplikasi SPA di fungsi ngOnDestroy (angular lifeCycle) Untuk setiap berlangganan Anda harus berhenti berlangganan . keuntungan => untuk mencegah negara menjadi terlalu berat.
misalnya: di component1:
dalam pelayanan:
dalam komponen2:
sumber
Untuk menangani langganan saya menggunakan kelas "Unsubscriber".
Berikut adalah Kelas Unsubscriber.
Dan Anda dapat menggunakan kelas ini di komponen / Layanan / Efek dll.
Contoh:
sumber
Anda dapat menggunakan
Subscription
kelas terbaru untuk berhenti berlangganan Observable dengan kode yang tidak terlalu berantakan.Kita dapat melakukan ini dengan
normal variable
tetapi itu akan adaoverride the last subscription
di setiap berlangganan baru jadi hindari itu, dan pendekatan ini sangat berguna ketika Anda berurusan dengan lebih banyak jumlah Obseravables, dan jenis Obeservables sepertiBehavoiurSubject
danSubject
Berlangganan
Anda dapat menggunakan ini dalam dua cara,
Anda dapat langsung mendorong langganan ke Array Berlangganan
menggunakan
add()
dariSubscription
A
Subscription
dapat menampung langganan anak dan dengan aman berhenti berlangganan semuanya. Metode ini menangani kemungkinan kesalahan (mis. Jika ada langganan anak nol).Semoga ini membantu.. :)
sumber
Paket SubSink, solusi mudah dan konsisten untuk berhenti berlangganan
Karena tidak ada orang lain yang menyebutkannya, saya ingin merekomendasikan paket Subsink yang dibuat oleh Ward Bell: https://github.com/wardbell/subsink#readme .
Saya telah menggunakannya pada suatu proyek jika kami adalah beberapa pengembang yang menggunakannya. Sangat membantu untuk memiliki cara yang konsisten yang berfungsi dalam setiap situasi.
sumber
Untuk yang dapat diobservasi yang selesai langsung setelah memancarkan hasil seperti
AsyncSubject
atau misalnya yang dapat diobservasi dari permintaan http dan Anda tidak perlu berhenti berlangganan. Tidak ada salahnya untuk memanggilunsubscribe()
mereka, tetapi jika diamati adalahclosed
metode berhenti berlangganan tidak akan melakukan apa-apa :Ketika Anda memiliki umur panjang yang dapat diamati yang memancarkan beberapa nilai dari waktu ke waktu (seperti misalnya a
BehaviorSubject
atau aReplaySubject
) Anda harus berhenti berlangganan untuk mencegah kebocoran memori.Anda dapat dengan mudah membuat observable yang selesai langsung setelah memancarkan hasil dari observable yang berumur panjang menggunakan operator pipa. Dalam beberapa jawaban di sini
take(1)
pipa disebutkan. Tapi aku lebih suka yangfirst()
pipa . Perbedaannyatake(1)
adalah:Keuntungan lain dari pipa pertama adalah Anda dapat melewati predikat yang akan membantu Anda mengembalikan nilai pertama yang memenuhi kriteria tertentu:
Pertama akan selesai secara langsung setelah memancarkan nilai pertama (atau ketika melewati argumen fungsi, nilai pertama yang memenuhi predikat Anda) sehingga tidak perlu berhenti berlangganan.
Kadang-kadang Anda tidak yakin apakah Anda telah lama diamati atau tidak. Saya tidak mengatakan ini adalah praktik yang baik tetapi Anda kemudian dapat selalu menambahkan
first
pipa hanya untuk memastikan Anda tidak perlu berhenti berlangganan secara manual. Menambahkanfirst
pipa tambahan pada observable yang hanya akan memancarkan satu nilai tidak ada salahnya.Selama pembangunan Anda dapat menggunakan dengan
single
pipa yang akan gagal jika sumber memancarkan diamati beberapa acara. Ini dapat membantu Anda menjelajahi jenis yang dapat diamati dan apakah perlu berhenti berlangganan atau tidak.The
first
dansingle
tampak sangat mirip, baik pipa dapat mengambil predikat opsional tetapi perbedaan yang penting dan baik diringkas dalam stackoverflow jawaban ini di sini :Catatan saya mencoba seakurat dan selengkap mungkin dalam jawaban saya dengan referensi ke dokumentasi resmi, tetapi tolong komentari jika ada sesuatu yang penting hilang ...
sumber
--- Perbarui Solusi Angular 9 dan Rxjs 6
unsubscribe
padangDestroy
siklus hidup Komponen SuduttakeUntil
di RxjsngOnInit
itu hanya terjadi satu kali ketika komponen init.Kami juga punya
async
pipa. Tapi, yang ini digunakan pada template (bukan di komponen Angular).sumber