Reaktif Programlama: RxJS ile Basit Akış ve Abonelik Örneği

Programlama Paradigmaları

Reaktif Programlama: RxJS ile Basit Akış ve Abonelik Örneği

Programlama Paradigmaları
4 dk okuma süresi
Bu yazıda reaktif programlama kavramlarını tanıtıyor, RxJS kullanarak basit akışlar ve abonelikler oluşturmayı örneklerle gösteriyoruz.
Reaktif Programlama: RxJS ile Basit Akış ve Abonelik Örneği

Giriş — Reaktif Programlama nedir ve neden RxJS?

Reaktif programlama, veri ve olay akışlarını birinci sınıf vatandaş olarak ele alan bir programlama paradigmasıdır. Bu yaklaşım, asenkron veri kaynaklarını (kullanıcı etkileşimleri, zamanlayıcılar, HTTP istekleri vb.) akışlar (streams) olarak modelleyip bu akışları birleştirme, dönüştürme ve yönetme imkânı sağlar. JavaScript dünyasında bu paradigmayı uygulayan popüler kütüphanelerden biri RxJS'tir; RxJS, gözlemlenebilirler (observables) ve kapsamlı operatör seti ile asenkron akışları yönetmeyi kolaylaştırır (daha fazla teknik detay için RxJS primer).

Bu rehberde ne öğreneceksiniz?

  • Temel kavramlar: Observable, Observer, Subscription, Operator
  • Basit ve pratik örnekler: fromEvent ile buton tıklaması, input arama örneği
  • Abonelik yönetimi ve bellek sızıntılarını önleme teknikleri
  • Hızlı uygulama adımları ve kontrol listesi

Temel Kavramlar (Kısa ve Pratik)

  • Observable (Gözlemlenebilir): Zaman içinde değer yayabilen bir yapıdır. Bir veri kaynağını (ör. DOM olayı, HTTP yanıtı) akışa dönüştürür. (Bakınız: RxJS primer).
  • Observer / Subscriber: Observable tarafından yayılan değerleri tüketen kod parçasıdır. subscribe ile kaydolunur.
  • Subscription: Aboneliğin yönetildiği nesnedir; unsubscribe ile durdurulabilir.
  • Operator: Akış üzerinde dönüşüm, filtreleme ya da birleştirme yapan fonksiyonlardır (ör. map, filter, debounceTime, switchMap).
  • Subject: Hem gözlemlenebilir hem gözlemci davranışı gösteren özel bir tiptir; birden fazla tüketiciye yayın yaparken kullanışlıdır.

Basit Örnek 1 — Buton Tıklamalarını Dinlemek (fromEvent)

Aşağıdaki örnek, DOM'daki bir butonun tıklama olayını RxJS ile nasıl dinleyebileceğinizi gösterir. fromEvent kullanımı RxJS dokümantasyonunda temel bir örnek olarak yer alır (kaynak).

Örnek kod (basit):
import { fromEvent } from 'rxjs';
const button = document.getElementById('myButton');
const buttonClicks = fromEvent(button, 'click');
const subscription = buttonClicks.subscribe(event => {
console.log('Butona tıklandı:', event);
});
// Gerektiğinde aboneliği iptal etmek için:
subscription.unsubscribe();

Açıklama: fromEvent DOM olayını bir Observable'a çevirir. subscribe çağrıldığında dinleme başlar; unsubscribe çağrıldığında dinleme sona erer.

Basit Örnek 2 — Arama Girişi: debounceTime ve switchMap

Gerçek dünyada kullanıcı yazarken her tuş basımında HTTP isteği göndermek istemezsiniz. debounceTime ve distinctUntilChanged ile istekleri yumuşatıp, switchMap ile önceki isteği iptal eden bir akış oluşturabilirsiniz. Bu desen RxJS ile sık kullanılan bir pratiktir (kavramlar için başlangıç rehberi ve dokümanlar faydalıdır).

Örnek kod (örnek API çağrısı):
import { fromEvent } from 'rxjs';
import { map, debounceTime, distinctUntilChanged, switchMap } from 'rxjs/operators';
const input = document.getElementById('searchInput');
const input$ = fromEvent(input, 'input').pipe(
debounceTime(300),
map((e) => e.target.value),
distinctUntilChanged(),
switchMap(query => fetch(`https://api.example.com/search?q=${encodeURIComponent(query)}`).then(res => res.json()))
); const sub = input$.subscribe({
next: results => console.log('Arama sonuçları:', results),
error: err => console.error('Arama hatası:', err)
}); // Component/uygulama kapanırken sub.unsubscribe(); çağrın veya takeUntil kullanın.

Açıklama: debounceTime yazma hızına bağlı olarak yayınları geciktirir, distinctUntilChanged aynı değerde tekrar yayın yapmaktan kaçınır; switchMap yeni bir sorgu başladığında eski sorguyu iptal eder. Bu kombinasyon, gereksiz ağ trafiğini azaltır ve UI'ı daha duyarlı kılar.

Hata Yönetimi ve Tamamlama

Observable'lar hata ve tamamlanma bildirimleri gönderebilir. subscribe çağırırken bir nesne şeklinde next, error ve complete fonksiyonlarını verebilirsiniz:

Örnek:
observable$.subscribe({
next: value => console.log(value),
error: err => console.error('Hata:', err),
complete: () => console.log('Tamamlandı')
});

Hataları yakalayıp işlemek için catchError gibi operatörleri pipe içinde kullanmak pratik bir yaklaşımdır.

Abonelik Yönetimi — Bellek Sızıntılarını Önleme

En yaygın hata, bileşen/komponent yok edildiğinde aboneliklerin iptal edilmemesidir. Bu durum bellek sızıntılarına ve beklenmeyen davranışlara yol açar. Önerilen yaklaşımlar:

  • Subscription nesnesini saklayıp component unmount/teardown sırasında unsubscribe çağırmak.
  • takeUntil operatörünü kullanıp bir 'destroy' Subject'i tetiklemek.
  • Framework'lerde (ör. Angular) async pipe kullanmak; angular async pipe otomatik unsubscribe yapar.

Bu teknikler RxJS ile güvenli abonelik yaşam döngüsü sağlamak için yaygın olarak önerilir (derinlemesine inceleme).

Pratik İpuçları ve Kontrol Listesi (Uygulama Odaklı)

  1. Önce akışı belirleyin: Hangi olaylar veriyi üretiyor? (click, input, timer, HTTP)
  2. Observable oluşturun: fromEvent, of, from, interval gibi üreticileri kullanın.
  3. pipe içinde operatörleri zincirleyin: map, filter, debounceTime, switchMap vb.
  4. subscribe ile tüketin; side-effect'leri burada yönetin.
  5. Abonelikleri yönetin: unsubscribe veya takeUntil ile temizleyin.
  6. Hataları yakalayın: catchError ve uygun kullanıcı geri bildirimi ekleyin.

Yaygın Hatalar ve Nasıl Kaçınılır?

  • Her event için doğrudan HTTP isteği göndermek: debounceTime + distinctUntilChanged ile azaltın.
  • Abonelikleri unutmak: component teardown'unda unsubscribe çağırın veya takeUntil kullanın.
  • Yanlış operatör seçimi: önce operatör davranışını (ör. mergeMap vs switchMap) test edin.

Özet ve İleri Okuma

Reaktif programlama, asenkron ve olay tabanlı uygulamalarda temiz ve ölçeklenebilir çözümler sunar. RxJS, JavaScript ekosisteminde bu paradigmayı uygulamak için zengin bir araç seti sağlar. Temel adımlar: olayları Observable'a dönüştürün, pipe ile dönüştürün, subscribe ile tüketin ve abonelikleri yönetin. Daha fazla teknik detay ve resmi dokümanlar için RxJS primer ve başlangıç rehberlerine göz atabilirsiniz: RxJS Primer, Bitovi RxJS Başlangıç ve Türkiye kaynakları için örnek bir giriş yazısı: SistersLab - RxJS ile Reaktif Programlama.


Hemen Deneyin

Basit bir HTML dosyası açıp yukarıdaki örnekleri deneyin. Küçük testler yaparak debounceTime, switchMap ve takeUntil gibi operatörlerin davranışlarını gözlemlemek öğrenmeyi hızlandırır.