Angular – ngOnDestroy | takeUntil | takeUntilDestroyed
Merhaba,
Bu içeriğimizde, Angular mimarisinde bundan yıllar önce de klavyeye alarak kritize ettiğimiz(bknz: Angular – Subscribe Durumlarında Memory Leaks Yönetimi İle Bellek Optimizasyonu) bir bellek optimizasyonu durumuna karşın güncel çözümlerle bakış atıyor olacağız. Kastettiğimiz durum, Angular’da ki Observable‘larla olan çalışma süreçlerindeki oluşturduğumuz subscribe’ları kapatmadığımız taktirde meydana gelen memory leaks durumlarıdır. Amacımız ise bu durumların göz ardı edilmeksizin, ihtiyaçlar sona erdiği taktirde mevcut subscribe’ların bir şekilde kapatılarak bellek optimizasyonunun bu aşamadaki eksikliğinin de gözetilmesini ve farkındalığını sağlamaktır. Aksi taktirde(biliyorsunuz ki) Observable‘lara abone olunduğunda, Angular bu abonelikleri canlı tutmakta ve ilgili component destroy edilse bile bu abonelikler iradeli bir şekilde sonlandırılmadığı taktirde hafızada yer tutmaya devam etmektedirler. İşte tam da bu noktada OnDestroy lifecycle(yaşam döngüsü) veya takeUntilDestroyed, takeUntilDestroyed gibi çeşitli RxJS stratejileri devreye girmektedir. Şimdi gelin bu stratejilerle mevzu bahis durumlara nasıl müdahale edildiğini tek tek inceleyelim;
OnDestroy Lifecycle Yaklaşımı
Esasında bu yöntemi yukarıdaki satırlarda referans ettiğim içeriğimizde unsubscribe Fonksiyonunun Kullanımı başlığı altında incelemiş bulunmaktayız. Evet, subscribe olunan bir Observable nesnesine OnDestroy lifecycle’ında aşağıdaki gibi unsubscribe metoduyla müdahale edebilir ve böylece component destroy edilirken mevcut olan tüm subscribe’ları keserek, memory leaks durumlarının önüne orta şeker geçebiliriz.
@Component({
selector: 'app-root',
standalone: true,
template: ``
})
export class AppComponent implements OnInit, OnDestroy {
httpClient: HttpClient = inject(HttpClient);
subscription: Subscription;
ngOnInit(): void {
this.subscription = this.httpClient.get("https://jsonplaceholder.typicode.com/posts")
.subscribe(data => console.log(data));
}
ngOnDestroy(): void {
if (this.subscription)
this.subscription.unsubscribe();
}
}
Orta şeker diyorum çünkü subscribe’ların kesilebilmesi için component’in destroy edilmesini beklememiz gerekmektedir. Halbuki kullanıcı deneyimi açısından component’in destroy edilmesi belki çok zaman sonra gerçekleştirilebilir.
Ayrıca ilgili içeriğe göz atarsanız eğer birden fazla subscribe’a da OnDestroy lifecycle’ında nasıl müdahale edileceğini ele aldığımızı göreceksiniz. Gidip, incelemenizi tavsiye ederim.
takeUntil Kullanımı
Bu strateji ise takeUntil RxJS operatörü ile birlikte bir Subject kullanılarak Observable‘ları yönetmemizi sağlamaktadır.
@Component({
selector: 'app-root',
standalone: true,
template: ``
})
export class AppComponent implements OnInit, OnDestroy {
httpClient: HttpClient = inject(HttpClient);
destroy$ = new Subject<void>();
ngOnInit(): void {
this.httpClient.get("https://jsonplaceholder.typicode.com/posts")
.pipe(takeUntil(this.destroy$))
.subscribe(data => console.log(data));
}
ngOnDestroy(): void {
this.destroy$.next();
this.destroy$.complete();
}
}
Buradaki temel amaç tüm subscribe’ları manuel olarak unsubscribe yapmak yerine takeUntil ile Subject‘ten sinyal verildiği an iptal edebilecek şekilde tasarlamaktır. OnDestroy yaklaşımına nazaran oldukça efektiftir.
takeUntilDestroyed Kullanımı
Ve son olarak subscribe’ları daha az kod yazarak yönetmemizi ve kesmemizi sağlayacak olan Angular 16 ile gelen takeUntilDestroyed RxJS operatörünü inceleyeceğiz. Bu operatör, takeUntil‘da olduğu gibi manuel olarak Subject ve OnDestroy kullanma ihtiyacını tamamen ortadan kaldırmakta, Angular component’lerine dair yaşam döngüsünü takip ederek abonelikleri component yok edildiğinde otomatik olarak iptal etmektedir.
@Component({
selector: 'app-root',
standalone: true,
template: ``
})
export class AppComponent implements OnInit {
httpClient: HttpClient = inject(HttpClient);
ngOnInit(): void {
this.httpClient.get("https://jsonplaceholder.typicode.com/posts")
.pipe(takeUntilDestroyed())
.subscribe(data => console.log(data));
}
}
Diğerlerine nazaran Angular yaşam döngüsüne entegre bir şekilde işleyen ve oldukça çağdaş yöntemdir diyebiliriz.
İlgilenenlerin faydalanması dileğiyle…
Sonraki yazılarımda görüşmek üzere…
İyi çalışmalar…
