RxJS Operatör Referansı
RxJS Operatör Referansı, Angular uygulamalarında reaktif programlamayı etkin bir şekilde kullanmak isteyen geliştiriciler için kritik bir kaynaktır. RxJS (Reactive Extensions for JavaScript), Observables üzerinden veri akışlarını yönetmeye yarayan güçlü operatörler sunar. Angular ile birlikte kullanıldığında, component tabanlı mimaride state yönetimi, veri akışı ve lifecycle hook’larının verimli kontrolünü sağlar. Bu referans, özellikle modern SPA projelerinde performans optimizasyonu ve hata yönetimi konularında geliştiricilere yol gösterir.
Bu referans, map, filter, switchMap, mergeMap, debounceTime, catchError gibi temel ve ileri seviye operatörlerin nasıl uygulanacağını, Observable’lar ile component içinde state’in nasıl yönetileceğini ve veri akışının nasıl kontrol edileceğini detaylı olarak gösterir. Okuyucu, component tabanlı tasarım, reactive formlar, HTTP istekleri ve kullanıcı etkileşimleri gibi senaryolarda RxJS operatörlerinin nasıl etkin bir şekilde kullanılacağını öğrenecektir. Bu sayede, gereksiz renderlardan kaçınmak, prop drilling sorununu önlemek ve uygulama performansını artırmak mümkün olur.
Temel Örnek
typescriptimport { Component, OnInit } from '@angular/core';
import { Observable, of } from 'rxjs';
import { map, filter } from 'rxjs/operators';
@Component({
selector: 'app-rxjs-basic',
template: ` <h2>Temel RxJS Örneği</h2> <ul> <li *ngFor="let item of filteredData">{{ item }}</li> </ul>
`
})
export class RxjsBasicComponent implements OnInit {
rawData$: Observable<number[]> = of([1, 2, 3, 4, 5, 6]);
filteredData: number[] = [];
ngOnInit(): void {
this.rawData$
.pipe(
filter(data => data.length > 0),
map(data => data.filter(num => num % 2 === 0))
)
.subscribe(result => this.filteredData = result);
}
}
Bu örnekte, RxjsBasicComponent içerisinde bir Observable tanımlanmıştır: rawData$. filter operatörü, boş array’leri dışlar ve map operatörü sadece çift sayıları seçer. Sonuç subscribe ile filteredData dizisine atanır ve template’de *ngFor ile görüntülenir. Bu yaklaşım, component lifecycle ile entegre edilmiştir ve prop drilling ile gereksiz render sorunlarını önler. Benzer mantık HTTP istekleri ve kullanıcı etkileşimlerinde de uygulanabilir.
Pratik Örnek
typescriptimport { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, of } from 'rxjs';
import { switchMap, tap, catchError } from 'rxjs/operators';
@Component({
selector: 'app-user-list',
template: ` <h2>Kullanıcı Listesi</h2> <div *ngIf="loading">Yükleniyor...</div> <ul> <li *ngFor="let user of users">{{ user.name }}</li> </ul> <div *ngIf="error">{{ error }}</div>
`
})
export class UserListComponent implements OnInit {
users: any[] = [];
loading = false;
error: string | null = null;
constructor(private http: HttpClient) {}
ngOnInit(): void {
this.loading = true;
this.http.get<any[]>('[https://jsonplaceholder.typicode.com/users](https://jsonplaceholder.typicode.com/users)')
.pipe(
tap(() => this.loading = false),
switchMap(data => of(data.filter(user => user.id % 2 === 0))),
catchError(err => {
this.error = 'Veri yüklenirken hata oluştu';
this.loading = false;
return of([]);
})
)
.subscribe(result => this.users = result);
}
}
Advanced Angular Implementation
typescriptimport { Injectable, Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { BehaviorSubject, Observable, of } from 'rxjs';
import { debounceTime, switchMap, map, catchError } from 'rxjs/operators';
@Injectable({ providedIn: 'root' })
export class ProductService {
private searchTerm$ = new BehaviorSubject<string>('');
constructor(private http: HttpClient) {}
setSearchTerm(term: string) {
this.searchTerm$.next(term);
}
getFilteredProducts(): Observable<any[]> {
return this.searchTerm$.pipe(
debounceTime(300),
switchMap(term =>
this.http.get<any[]>('[https://api.example.com/products').pipe(](https://api.example.com/products'%29.pipe%28)
map(products => products.filter(p => p.name.includes(term))),
catchError(() => of([]))
)
)
);
}
}
@Component({
selector: 'app-product-list',
template: ` <input type="text" (input)="onSearch($event.target.value)" placeholder="Ürün Ara"> <ul> <li *ngFor="let product of products$ | async">{{ product.name }}</li> </ul>
`
})
export class ProductListComponent implements OnInit {
products$: Observable<any[]> = of([]);
constructor(private productService: ProductService) {}
ngOnInit(): void {
this.products$ = this.productService.getFilteredProducts();
}
onSearch(term: string) {
this.productService.setSearchTerm(term);
}
}
Bu ileri seviye örnekte, BehaviorSubject ve debounceTime ile reactive search uygulanmıştır. switchMap sadece son değeri işler, catchError hataları yönetir. Servis üzerinden state yönetimi ve component ayrımı, tekrar kullanılabilirlik ve test edilebilirlik sağlar. async Pipe ile abonelik yönetimi otomatikleşir ve bellek sızıntıları önlenir. Bu örnek, Angular lifecycle hook’ları ve reactive state yönetimini birleştirerek performans ve ölçeklenebilirlik sağlar.
Angular best practices ve yaygın hatalar: Component’leri mümkün olduğunca hafif tutun, state yönetimi için servisleri kullanın. Template’lerde async Pipe kullanın, yan etkiler için tap operatöründen yararlanın. State’i doğrudan değiştirmekten kaçının, HTTP hatalarını göz ardı etmeyin ve switchMap/mergeMap kullanımında dikkatli olun. Performans için debounceTime ve distinctUntilChanged kullanın. catchError ile uygulama dayanıklılığı artırılabilir. Angular DevTools ile debug ve veri akışı izlenebilir.
📊 Kapsamlı Referans
| Operator | Description | Syntax | Example | Notes |
|---|---|---|---|---|
| map | Observable değerlerini dönüştürür | observable.pipe(map(val => transform(val))) | of(1,2,3).pipe(map(x => x*2)) | Veri transformasyonu |
| filter | Observable değerlerini filtreler | observable.pipe(filter(val => condition(val))) | of(1,2,3).pipe(filter(x => x>1)) | Koşullu filtreleme |
| switchMap | Önceki Observable’ı iptal eder | observable.pipe(switchMap(val => newObs)) | http.get('/api').pipe(switchMap(res => http.get('/api2'))) | Asenkron akış yönetimi |
| mergeMap | Birden fazla Observable’ı birleştirir | observable.pipe(mergeMap(val => newObs)) | Concurrency akışı | |
| concatMap | Emit sırasını korur | observable.pipe(concatMap(val => newObs)) | Sıralı işleme | |
| tap | Yan etkiler için kullanılır | observable.pipe(tap(val => console.log(val))) | Logging/debug | |
| catchError | Hataları yönetir | observable.pipe(catchError(err => of(default))) | Dayanıklılık | |
| debounceTime | Değerlerin emit edilmesini geciktirir | observable.pipe(debounceTime(300)) | Input optimizasyonu | |
| distinctUntilChanged | Tekrarlayan değerleri engeller | observable.pipe(distinctUntilChanged()) | Gereksiz render önleme | |
| combineLatest | Multiple Observable’ları birleştirir | combineLatest([obs1, obs2]).pipe(map(...)) | Akış senkronizasyonu |
📊 Complete Angular Properties Reference
| Property | Values | Default | Description | Angular Support |
|---|---|---|---|---|
| async | Observable | null | Template’de Observable bağlama | Angular 2+ |
| BehaviorSubject | Subject | null | Mevcut değeri saklar | Angular 2+ |
| pipe | Function | – | Operator kompozisyonu | Angular 2+ |
| subscribe | Function | – | Observable çalıştırma | Angular 2+ |
| tap | Function | – | Yan etkiler | Angular 2+ |
| catchError | Function | – | Hata yönetimi | Angular 6+ |
| switchMap | Function | – | Observable değiştirme | Angular 5+ |
| mergeMap | Function | – | Observable birleştirme | Angular 5+ |
| debounceTime | Number | 0 | Emit gecikmesi | Angular 5+ |
| distinctUntilChanged | Function | – | Tekrarlayan değerleri engelleme | Angular 5+ |
| shareReplay | Number | 1 | Değer paylaşımı ve cache | Angular 5+ |
| startWith | Value | – | Başlangıç değeri | Angular 5+ |
Özet ve sonraki adımlar: RxJS Operatör Referansı, Angular’da reactive state yönetimini öğrenmek ve SPA’larda performans optimizasyonu sağlamak için kritiktir. exhaustMap, bufferTime ve window gibi ileri seviye operatörleri öğrenmek, NgRx veya Akita gibi state yönetim kütüphaneleri ile kombinasyonları denemek önerilir. async Pipe, lifecycle hook’ları ve hata yönetimi ile pratik uygulamalar geliştirerek reaktif programlama becerilerinizi geliştirin.
🧠 Bilginizi Test Edin
Bilginizi Test Edin
Bu interaktif sınavla kendini test et ve konuyu ne kadar iyi anladığını gör
📝 Talimatlar
- Her soruyu dikkatle okuyun
- Her soru için en iyi cevabı seçin
- Quiz'i istediğiniz kadar tekrar alabilirsiniz
- İlerlemeniz üstte gösterilecek