--- एडिट 4 - अतिरिक्त संसाधन (2018/09/01)
एंगुलर बेन लेश और वार्ड बेल में एडवेंचर्स के एक हालिया एपिसोड में एक घटक में अनसब्सक्राइब कैसे / कब करना है, इसके बारे में चर्चा करें। चर्चा लगभग 1:05:30 से शुरू होती है।
वार्ड उल्लेख right now there's an awful takeUntil dance that takes a lot of machinery
और Shai Reznik का उल्लेख है Angular handles some of the subscriptions like http and routing
।
प्रतिक्रिया में बेन का उल्लेख है कि अभी वेधशालाओं को कोणीय घटक जीवन चक्र की घटनाओं में शामिल होने की अनुमति देने के लिए चर्चाएं हैं और वार्ड जीवनरेखा घटनाओं के एक अवलोकन का सुझाव देता है कि घटक को आंतरिक स्थिति के रूप में वेधशालाओं को पूरा करने के तरीके के रूप में जानने के लिए एक घटक सदस्यता ले सकता है।
उस ने कहा, हमें अब समाधान की आवश्यकता है इसलिए यहां कुछ अन्य संसाधन हैं।
takeUntil()
RxJs कोर टीम के सदस्य निकोलस जैमिसन से पैटर्न के लिए एक सिफारिश और इसे लागू करने में मदद करने के लिए एक tslint नियम। https://ncjamieson.com/avoiding-takeuntil-leaks/
लाइटवेट एनपीएम पैकेज जो एक ऑब्जर्वेबल ऑपरेटर को उजागर करता है जो this
एक पैरामीटर उदाहरण ( ) को एक पैरामीटर के रूप में लेता है और स्वचालित रूप से अनसब्सक्राइब करता है ngOnDestroy
।
https://github.com/NetanelBasal/ngx-take-until-destroy
यदि आप एओटी बिल्ड नहीं कर रहे हैं (लेकिन हम सभी अब एओटी कर रहे हैं) के साथ थोड़ा बेहतर एर्गोनॉमिक्स के साथ ऊपर का एक और बदलाव।
https://github.com/smnbbrv/ngx-rx-collector
कस्टम निर्देश *ngSubscribe
जो async पाइप की तरह काम करता है, लेकिन आपके टेम्पलेट में एक एम्बेडेड दृश्य बनाता है ताकि आप अपने पूरे टेम्पलेट में 'अलिखित' मान का उल्लेख कर सकें।
https://netbasal.com/diy-subscription-handling-directive-in-angular-c8f6e762697f
मैं निकोलस के ब्लॉग पर एक टिप्पणी में उल्लेख करता हूं कि अति का उपयोग इस बात का takeUntil()
संकेत हो सकता है कि आपका घटक बहुत अधिक करने की कोशिश कर रहा है और आपके मौजूदा घटकों को फ़ीचर और प्रस्तुति घटकों में अलग करना चाहिए। तब आप | async
फ़ीचर घटक Input
से प्रेज़ेंटेशनल घटक में ऑब्ज़र्वेबल को देख सकते हैं, जिसका अर्थ है कि कहीं भी कोई सदस्यता आवश्यक नहीं है। इस दृष्टिकोण के बारे में यहाँ और पढ़ें
--- संपादन 3 - 'आधिकारिक' समाधान (2017/04/09)
मैंने NGConf में इस सवाल के बारे में वार्ड बेल के साथ बात की थी (मैंने उसे यह उत्तर भी दिखाया था जो उसने कहा था कि वह सही है) लेकिन उसने मुझे बताया कि अंगुलियों के लिए डॉक्स टीम ने इस सवाल का हल खोजा है जो अप्रकाशित है (हालांकि वे इसे मंजूरी मिलने पर काम कर रहे हैं) )। उन्होंने मुझे यह भी बताया कि मैं आगामी आधिकारिक सिफारिश के साथ अपने एसओ उत्तर को अपडेट कर सकता हूं।
हम सभी को आगे बढ़ने के लिए जो उपाय करना चाहिए, वह है उन private ngUnsubscribe = new Subject();
सभी घटकों के लिए एक क्षेत्र जोड़ना, जिनके पास अपने वर्ग कोड के भीतर .subscribe()
कॉल करने के लिए कॉल है Observable
।
हम तो this.ngUnsubscribe.next(); this.ngUnsubscribe.complete();
हमारे ngOnDestroy()
तरीकों में कहते हैं ।
गुप्त सॉस (जैसा कि @metamaker द्वारा पहले ही नोट किया गया है ) takeUntil(this.ngUnsubscribe)
हमारे प्रत्येक कॉल से पहले .subscribe()
कॉल करना है जो सभी सदस्यता को गारंटी देगा कि घटक नष्ट होने पर साफ हो जाएगा।
उदाहरण:
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();
}
}
नोट:takeUntil
ऑपरेटर श्रृंखला में मध्यवर्ती पर्यवेक्षकों के साथ लीक को रोकने के लिए ऑपरेटर को अंतिम एक के रूप में जोड़ना महत्वपूर्ण है ।
--- संपादित 2 (2016/12/28)
स्रोत 5
कोणीय ट्यूटोरियल, राउटिंग चैप्टर अब निम्नलिखित बताता है: "राउटर अपने द्वारा प्रदान की जाने वाली वेधशालाओं का प्रबंधन करता है और सब्सक्रिप्शन को स्थानीय करता है। घटक के नष्ट होने पर सब्सक्रिप्शन की सफाई हो जाती है, मेमोरी लीक से बचाव होता है, इसलिए हमें सदस्यता समाप्त करने की आवश्यकता नहीं है। मार्ग अवलोकन योग्य है। " - मार्क राजकोक
यहां राउटर वेधशालाओं के बारे में कोणीय डॉक्स के लिए गितुब मुद्दों पर चर्चा की गई है जहां वार्ड बेल का उल्लेख है कि इस सब के लिए स्पष्टीकरण कार्यों में है।
--- संपादित करें 1
स्रोत 4
NgEurope Rob Wormald के इस वीडियो में यह भी कहा गया है कि आपको Router Observables से अनसब्सक्राइब करने की आवश्यकता नहीं है। उन्होंने नवंबर 2016 सेhttp
सेवा और ActivatedRoute.params
इस वीडियो का भी उल्लेख किया ।
--- मूल उत्तर
TLDR:
इस प्रश्न के लिए (2) प्रकार हैं Observables
- परिमित मूल्य और अनंत मूल्य।
http
Observables
उत्पादन परिमित (1) मूल्य और एक डोम की तरह कुछ अनंत मूल्यों का event listener
Observables
उत्पादन ।
आप मैन्युअल रूप से कॉल करते हैं subscribe
(async पाइप का उपयोग नहीं), तो unsubscribe
से अनंत Observables
।
के बारे में चिंता मत करो परिमित हैं, RxJs
उनकी देखभाल करेगा।
स्रोत 1
मैंने यहां एंगुलर के गटर में रोब वर्मल्ड के एक जवाब को ट्रैक किया ।
वह कहता है (मैं स्पष्टता के लिए पुनर्गठित हूं और जोर मेरा है)
यदि इसका एकल-मान-अनुक्रम (http अनुरोध की तरह) मैनुअल क्लीनअप अनावश्यक है (मान लें कि आप कंट्रोलर में मैन्युअल रूप से सदस्यता लेते हैं)
मुझे कहना चाहिए "यदि इसका एक अनुक्रम जो पूरा होता है " (जिनमें से एकल मूल्य अनुक्रम, एक ला http, एक हैं)
यदि इसका एक अनंत क्रम है , तो आपको उसे अनसब्सक्राइब कर देना चाहिए जो आपके लिए async पाइप करता है
इसके अलावा वे ऑब्जर्वबल्स पर इस यूट्यूब वीडियो में उल्लेख करते हैं कि they clean up after themselves
... वेधशालाओं के संदर्भ में complete
(जैसे कि वादे, जो हमेशा पूरे होते हैं क्योंकि वे हमेशा 1 मूल्य और समाप्ति का उत्पादन कर रहे हैं - हम कभी भी वादा करने से इनकार करने के बारे में चिंता नहीं करते हैं कि वे साफ सुथरी xhr
घटना को सुनिश्चित करते हैं। श्रोताओं, सही?)।
स्रोत 2
इसके अलावा रैंगल गाइड में कोणीय 2 तक यह पढ़ता है
ज्यादातर मामलों में हमें अनसब्सक्राइब विधि को स्पष्ट रूप से कॉल करने की आवश्यकता नहीं होगी, जब तक कि हम जल्दी रद्द नहीं करना चाहते हैं या हमारे ऑब्जर्वेबल के पास हमारी सदस्यता से अधिक लंबी उम्र है। अवलोकन योग्य ऑपरेटरों का डिफ़ॉल्ट व्यवहार सदस्यता के निपटान के लिए है। जल्द ही .complete () या .error () संदेश प्रकाशित किए जाते हैं। ध्यान रखें कि RxJS को ज्यादातर समय "आग और भूल" फैशन में इस्तेमाल करने के लिए डिज़ाइन किया गया था।
वाक्यांश कब our Observable has a longer lifespan than our subscription
लागू होता है?
यह तब लागू होता है जब किसी घटक के अंदर एक सदस्यता बनाई जाती है जो पूर्ण होने से पहले नष्ट हो जाती है (या 'बहुत पहले' नहीं) Observable
।
मैंने इसे अर्थ के रूप में पढ़ा यदि हम एक http
अनुरोध या एक अवलोकन योग्य है जो 10 मानों का उत्सर्जन करता है और हमारे घटक उस http
अनुरोध के वापस आने से पहले नष्ट हो जाते हैं या 10 मानों को उत्सर्जित कर दिया गया है, हम अभी भी ठीक हैं!
जब अनुरोध वापस आ जाता है या 10 वें मूल्य को अंतिम रूप Observable
से पूरा कर लिया जाता है और सभी संसाधनों को साफ कर दिया जाएगा।
स्रोत 3
यदि हम इस उदाहरण को उसी Rangle गाइड से देखते हैं तो हम देख सकते हैं कि Subscription
करने की route.params
आवश्यकता है unsubscribe()
क्योंकि हमें नहीं पता है कि कब params
बदलना बंद हो जाएगा (नए मूल्यों का उत्सर्जन)।
घटक को नेविगेट करके नष्ट किया जा सकता है जिस स्थिति में मार्ग परिमाण अभी भी बदलते रहेंगे (वे तकनीकी रूप से ऐप समाप्त होने तक बदल सकते हैं) और सदस्यता में आवंटित संसाधनों को अभी भी आवंटित किया जाएगा क्योंकि वहाँ कोई नहीं है completion
।
Subscription
कियाhttp-requests
जा सकता है, क्योंकि वे केवलonNext
एक बार कॉल करते हैं और फिर वे कॉल करते हैंonComplete
। इसकेRouter
बजायonNext
बार-बार कॉल करता है और शायद कभी कॉलonComplete
नहीं करता (उस बारे में निश्चित नहीं ...)। उसीObservable
सेEvent
s के लिए जाता है । इसलिए मुझे लगता है कि उन्हें होना चाहिएunsubscribed
।