Anulowanie subskrypcji i wycieki pamięci
Unikaj wycieków za pomocą takeUntilDestroyed.
Anulowanie subskrypcji i wycieki pamięci to bezpłatna lekcja Angular Academy na CoddyKit. To lekcja 3 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Angular Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Angular Academy zawiera 4 lekcji w sumie.
Problem wycieku pamięci
Jeśli zasubskrybujesz długotrwały Observable w komponencie i nigdy nie anulujesz subskrypcji, wywołanie zwrotne będzie działać także po zniszczeniu komponentu. Powoduje to wyciek pamięci oraz może prowadzić do błędów lub wielokrotnego wykonywania tej samej pracy.
Ręczne anulowanie subskrypcji
Podstawowe rozwiązanie: zapisz obiekt Subscription i anuluj subskrypcję w ngOnDestroy.
import { Component, OnDestroy } from '@angular/core';
import { Subscription, interval } from 'rxjs';
export class WidgetComponent implements OnDestroy {
private sub = interval(1000).subscribe(n => console.log(n));
ngOnDestroy() { this.sub.unsubscribe(); }
}Zarządzanie wieloma subskrypcjami
Pojedynczy obiekt Subscription może gromadzić podrzędne subskrypcje za pomocą .add(), a jedno wywołanie unsubscribe() zakończy je wszystkie.
private subs = new Subscription();
ngOnInit() {
this.subs.add(a$.subscribe());
this.subs.add(b$.subscribe());
}
ngOnDestroy() { this.subs.unsubscribe(); }takeUntilDestroyed
Angular udostępnia funkcję takeUntilDestroyed(), która automatycznie kończy strumień po zniszczeniu komponentu — nie trzeba ręcznie implementować ngOnDestroy.
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
export class WidgetComponent {
constructor() {
interval(1000)
.pipe(takeUntilDestroyed())
.subscribe(n => console.log(n));
}
}Wymagany kontekst wstrzykiwania
Wywołane bez argumentu takeUntilDestroyed() musi działać w kontekście wstrzykiwania (na przykład w konstruktorze). Poza nim należy jawnie przekazać DestroyRef.
import { inject, DestroyRef } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
const destroyRef = inject(DestroyRef);
ngOnInit() {
source$.pipe(takeUntilDestroyed(destroyRef)).subscribe();
}Klasyczny wzorzec takeUntil
Przed wprowadzeniem takeUntilDestroyed standardowy wzorzec korzystał z obiektu Subject, który emitował wartość w ngOnDestroy.
private destroy$ = new Subject<void>();
ngOnInit() {
source$.pipe(takeUntil(this.destroy$)).subscribe();
}
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
}Strumienie, które się kończą, nie wymagają sprzątania
Żądania HttpClient emitują wartość raz, a następnie się kończą, więc same zwalniają zasoby. Zwykle nie trzeba anulować subskrypcji pojedynczego żądania HTTP — choć użycie takeUntilDestroyed jest nadal bezpieczne.
Potok async robi to za Państwa
Najlepsze podejście w szablonach to pozwolić potokowi async automatycznie subskrybować i anulować subskrypcję. Omówimy go w następnej lekcji.
// template:
// <div>{{ user$ | async | json }}</div>
// No manual subscribe / unsubscribe neededObjawy wycieku subskrypcji
Duplikowane żądania sieciowe, procedury obsługi uruchamiane po przejściu do innego widoku, rosnące zużycie pamięci w narzędziach deweloperskich lub błędy „Cannot read property of destroyed view” często wskazują na zapomniane anulowanie subskrypcji.
toSignal również automatycznie zwalnia zasoby
Konwersja Observable na sygnał za pomocą toSignal() również automatycznie anuluje subskrypcję po zniszczeniu kontekstu, który jest jej właścicielem.
import { toSignal } from '@angular/core/rxjs-interop';
user = toSignal(this.http.get('/api/me'));
// auto-unsubscribed on destroyWybór podejścia
W szablonach preferuj potok async lub toSignal; w przypadku ręcznych subskrypcji używaj takeUntilDestroyed(); po kolekcję Subscription sięgaj tylko wtedy, gdy jest to konieczne.
Szybkie sprawdzenie
Sprawdź swoją wiedzę o anulowaniu subskrypcji.
Podsumowanie: Anulowanie subskrypcji i wycieki pamięci
Zawsze kończ działanie długotrwałych subskrypcji.
takeUntilDestroyed()automatycznie kończy strumień podczas niszczenia.- Potok
asyncitoSignal()zarządzają subskrypcjami za Państwa. - Pojedyncze żądania HTTP kończą się samoczynnie.
Następnie: potok async szczegółowo.
Często zadawane pytania
Czy lekcja „Anulowanie subskrypcji i wycieki pamięci” jest bezpłatna?
Tak — pełny tekst „Anulowanie subskrypcji i wycieki pamięci” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Angular Academy, przejdź na CoddyKit PRO. Kurs Angular Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Anulowanie subskrypcji i wycieki pamięci”?
Unikaj wycieków za pomocą takeUntilDestroyed. Ćwiczysz Angular Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Angular Academy?
Nie wymagamy żadnego doświadczenia. Angular Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 4.
Ile czasu zajmuje lekcja „Anulowanie subskrypcji i wycieki pamięci”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Angular Academy?
Tak. Każda lekcja Angular Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Obserwowalne i subskrypcje
- Subjects i BehaviorSubject
- Anulowanie subskrypcji i wycieki pamięci
- Potok async