﻿
{"id":27419,"date":"2024-12-18T08:17:21","date_gmt":"2024-12-18T08:17:21","guid":{"rendered":"https:\/\/www.gencayyildiz.com\/blog\/?p=27419"},"modified":"2024-12-18T08:17:53","modified_gmt":"2024-12-18T08:17:53","slug":"angular-ngondestroy-takeuntil-takeuntildestroyed","status":"publish","type":"post","link":"https:\/\/www.gencayyildiz.com\/blog\/angular-ngondestroy-takeuntil-takeuntildestroyed\/","title":{"rendered":"Angular &#8211; ngOnDestroy | takeUntil | takeUntilDestroyed"},"content":{"rendered":"<div id=\"fb-root\"><\/div>\n<p>Merhaba,<\/p>\n<p>Bu i\u00e7eri\u011fimizde, Angular mimarisinde bundan y\u0131llar \u00f6nce de klavyeye alarak kritize etti\u011fimiz<span style=\"font-size:12px;\">(bknz: <a href=\"https:\/\/www.gencayyildiz.com\/blog\/angular-subscribe-durumlarinda-memory-leaks-yonetimi-ile-bellek-optimizasyonu\/\" target=\"_blank\">Angular \u2013 Subscribe Durumlar\u0131nda Memory Leaks Y\u00f6netimi \u0130le Bellek Optimizasyonu<\/a>)<\/span> bir bellek optimizasyonu durumuna kar\u015f\u0131n g\u00fcncel \u00e7\u00f6z\u00fcmlerle bak\u0131\u015f at\u0131yor olaca\u011f\u0131z. Kastetti\u011fimiz durum, Angular&#8217;da ki <code>Observable<\/code>&#8216;larla olan \u00e7al\u0131\u015fma s\u00fcre\u00e7lerindeki olu\u015fturdu\u011fumuz subscribe&#8217;lar\u0131 kapatmad\u0131\u011f\u0131m\u0131z taktirde meydana gelen memory leaks durumlar\u0131d\u0131r. Amac\u0131m\u0131z ise bu durumlar\u0131n g\u00f6z ard\u0131 edilmeksizin, ihtiya\u00e7lar sona erdi\u011fi taktirde mevcut subscribe&#8217;lar\u0131n bir \u015fekilde kapat\u0131larak bellek optimizasyonunun bu a\u015famadaki eksikli\u011finin de g\u00f6zetilmesini ve fark\u0131ndal\u0131\u011f\u0131n\u0131 sa\u011flamakt\u0131r. Aksi taktirde(biliyorsunuz ki) <code>Observable<\/code>&#8216;lara abone olundu\u011funda, Angular bu abonelikleri canl\u0131 tutmakta ve ilgili component destroy edilse bile bu abonelikler iradeli bir \u015fekilde sonland\u0131r\u0131lmad\u0131\u011f\u0131 taktirde haf\u0131zada yer tutmaya devam etmektedirler. \u0130\u015fte tam da bu noktada <code>OnDestroy<\/code> lifecycle(ya\u015fam d\u00f6ng\u00fcs\u00fc) veya <code>takeUntilDestroyed<\/code>, <code>takeUntilDestroyed<\/code> gibi \u00e7e\u015fitli RxJS stratejileri devreye girmektedir. \u015eimdi gelin bu stratejilerle mevzu bahis durumlara nas\u0131l m\u00fcdahale edildi\u011fini tek tek inceleyelim;<\/p>\n<h4>OnDestroy Lifecycle Yakla\u015f\u0131m\u0131<\/h4>\n<p>Esas\u0131nda bu y\u00f6ntemi yukar\u0131daki sat\u0131rlarda referans etti\u011fim i\u00e7eri\u011fimizde <strong>unsubscribe Fonksiyonunun Kullan\u0131m\u0131<\/strong> ba\u015fl\u0131\u011f\u0131 alt\u0131nda incelemi\u015f bulunmaktay\u0131z. Evet, subscribe olunan bir <code>Observable<\/code> nesnesine <code>OnDestroy<\/code> lifecycle&#8217;\u0131nda a\u015fa\u011f\u0131daki gibi <em>unsubscribe<\/em> metoduyla m\u00fcdahale edebilir ve b\u00f6ylece component destroy edilirken mevcut olan t\u00fcm subscribe&#8217;lar\u0131 keserek, memory leaks durumlar\u0131n\u0131n \u00f6n\u00fcne orta \u015feker ge\u00e7ebiliriz.<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n@Component({\r\n  selector: 'app-root',\r\n  standalone: true,\r\n  template: ``\r\n})\r\nexport class AppComponent implements OnInit, OnDestroy {\r\n  httpClient: HttpClient = inject(HttpClient);\r\n\r\n  subscription: Subscription;\r\n  ngOnInit(): void {\r\n    this.subscription = this.httpClient.get(&quot;https:\/\/jsonplaceholder.typicode.com\/posts&quot;)\r\n      .subscribe(data =&gt; console.log(data));\r\n  }\r\n\r\n  ngOnDestroy(): void {\r\n    if (this.subscription)\r\n      this.subscription.unsubscribe();\r\n  }\r\n}\r\n<\/pre>\n<\/div>\n<p>Orta \u015feker diyorum \u00e7\u00fcnk\u00fc subscribe&#8217;lar\u0131n kesilebilmesi i\u00e7in component&#8217;in destroy edilmesini beklememiz gerekmektedir. Halbuki kullan\u0131c\u0131 deneyimi a\u00e7\u0131s\u0131ndan component&#8217;in destroy edilmesi belki \u00e7ok zaman sonra ger\u00e7ekle\u015ftirilebilir.<\/p>\n<p>Ayr\u0131ca ilgili i\u00e7eri\u011fe g\u00f6z atarsan\u0131z e\u011fer birden fazla subscribe&#8217;a da <code>OnDestroy<\/code> lifecycle&#8217;\u0131nda nas\u0131l m\u00fcdahale edilece\u011fini ele ald\u0131\u011f\u0131m\u0131z\u0131 g\u00f6receksiniz. Gidip, incelemenizi tavsiye ederim.<\/p>\n<h4>takeUntil Kullan\u0131m\u0131<\/h4>\n<p>Bu strateji ise <code>takeUntil<\/code> RxJS operat\u00f6r\u00fc ile birlikte bir <code>Subject<\/code> kullan\u0131larak <code>Observable<\/code>&#8216;lar\u0131 y\u00f6netmemizi sa\u011flamaktad\u0131r.<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n@Component({\r\n  selector: 'app-root',\r\n  standalone: true,\r\n  template: ``\r\n})\r\nexport class AppComponent implements OnInit, OnDestroy {\r\n  httpClient: HttpClient = inject(HttpClient);\r\n\r\n  destroy$ = new Subject&lt;void&gt;();\r\n  ngOnInit(): void {\r\n    this.httpClient.get(&quot;https:\/\/jsonplaceholder.typicode.com\/posts&quot;)\r\n      .pipe(takeUntil(this.destroy$))\r\n      .subscribe(data =&gt; console.log(data));\r\n  }\r\n\r\n  ngOnDestroy(): void {\r\n    this.destroy$.next();\r\n    this.destroy$.complete();\r\n  }\r\n}\r\n<\/pre>\n<\/div>\n<p>Buradaki temel ama\u00e7 t\u00fcm subscribe&#8217;lar\u0131 manuel olarak <em>unsubscribe<\/em> yapmak yerine <code>takeUntil<\/code> ile <code>Subject<\/code>&#8216;ten sinyal verildi\u011fi an iptal edebilecek \u015fekilde tasarlamakt\u0131r. <code>OnDestroy<\/code> yakla\u015f\u0131m\u0131na nazaran olduk\u00e7a efektiftir.<\/p>\n<h4>takeUntilDestroyed Kullan\u0131m\u0131<\/h4>\n<p>Ve son olarak subscribe&#8217;lar\u0131 daha az kod yazarak y\u00f6netmemizi ve kesmemizi sa\u011flayacak olan Angular 16 ile gelen <code>takeUntilDestroyed<\/code> RxJS operat\u00f6r\u00fcn\u00fc inceleyece\u011fiz. Bu operat\u00f6r, <code>takeUntil<\/code>&#8216;da oldu\u011fu gibi manuel olarak <code>Subject<\/code> ve <code>OnDestroy<\/code> kullanma ihtiyac\u0131n\u0131 tamamen ortadan kald\u0131rmakta, Angular component&#8217;lerine dair ya\u015fam d\u00f6ng\u00fcs\u00fcn\u00fc takip ederek abonelikleri component yok edildi\u011finde otomatik olarak iptal etmektedir.<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n@Component({\r\n  selector: 'app-root',\r\n  standalone: true,\r\n  template: ``\r\n})\r\nexport class AppComponent implements OnInit {\r\n  httpClient: HttpClient = inject(HttpClient);\r\n\r\n  ngOnInit(): void {\r\n    this.httpClient.get(&quot;https:\/\/jsonplaceholder.typicode.com\/posts&quot;)\r\n      .pipe(takeUntilDestroyed())\r\n      .subscribe(data =&gt; console.log(data));\r\n  }\r\n}\r\n<\/pre>\n<\/div>\n<p>Di\u011ferlerine nazaran Angular ya\u015fam d\u00f6ng\u00fcs\u00fcne entegre bir \u015fekilde i\u015fleyen ve olduk\u00e7a \u00e7a\u011fda\u015f y\u00f6ntemdir diyebiliriz.<\/p>\n<p>\u0130lgilenenlerin faydalanmas\u0131 dile\u011fiyle&#8230;<br \/>\nSonraki yaz\u0131lar\u0131mda g\u00f6r\u00fc\u015fmek \u00fczere&#8230;<br \/>\n\u0130yi \u00e7al\u0131\u015fmalar&#8230;<\/p>\n<!-- AddThis Advanced Settings generic via filter on the_content --><!-- AddThis Share Buttons generic via filter on the_content -->","protected":false},"excerpt":{"rendered":"<p>Merhaba, Bu i\u00e7eri\u011fimizde, Angular mimarisinde bundan y\u0131llar \u00f6nce de klavyeye alarak kritize etti\u011fimiz(bknz: Angular \u2013 Subscribe Durumlar\u0131nda Memory Leaks Y\u00f6netimi \u0130le Bellek Optimizasyonu) bir bellek optimizasyonu durumuna kar\u015f\u0131n g\u00fcncel \u00e7\u00f6z\u00fcmlerle bak\u0131\u015f at\u0131yor olaca\u011f\u0131z. Kastetti\u011fimiz&#46;&#46;&#46;<!-- AddThis Advanced Settings generic via filter on get_the_excerpt --><!-- AddThis Share Buttons generic via filter on get_the_excerpt --><\/p>\n","protected":false},"author":1,"featured_media":26698,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2420],"tags":[2156,5197,5195,5196],"class_list":["post-27419","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-angular","tag-angular","tag-angular-takeuntildestroyed","tag-ngondestroy","tag-takeuntildestroyed"],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/27419","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/comments?post=27419"}],"version-history":[{"count":5,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/27419\/revisions"}],"predecessor-version":[{"id":27427,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/27419\/revisions\/27427"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media\/26698"}],"wp:attachment":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media?parent=27419"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/categories?post=27419"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/tags?post=27419"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}