مرجع عملگرهای RxJS
مرجع عملگرهای RxJS در انگولار یک ابزار قدرتمند برای مدیریت جریانهای دادهای غیرهمزمان و طراحی برنامههای مدرن مبتنی بر component است. RxJS (Reactive Extensions for JavaScript) امکان ترکیب، فیلتر و تبدیل دادهها در Observables را فراهم میکند و به توسعهدهندگان اجازه میدهد تا state برنامه را به شکل پیشبینیپذیر و موثر مدیریت کنند. در انگولار، استفاده از عملگرهای RxJS مانند map، filter، switchMap و mergeMap به کاهش prop drilling و جلوگیری از re-render های غیرضروری کمک میکند و جریان دادهها را در سراسر lifecycle componentها بهینه میسازد.
این مرجع به توسعهدهندگان نشان میدهد که چگونه میتوانند با استفاده از Observables و عملگرهای RxJS، componentهای قابل استفاده مجدد و maintainable بسازند و عملیات غیرهمزمان مانند درخواستهای API، eventهای کاربر و WebSocketها را به شکل ریاکتیو مدیریت کنند. با یادگیری این مفاهیم، توسعهدهنده میتواند برنامههایی با performance بالا و ساختار مدرن SPAs طراحی کند.
در این سند، خواننده با مثالهای عملی و patterns مناسب انگولار آشنا میشود، از جمله مدیریت state، بهینهسازی جریان دادهها، استفاده از lifecycle hooks و error handling پیشرفته. هدف این مرجع، ایجاد درک عمیق از نقش RxJS در طراحی component-based و توسعه برنامههای انگولار enterprise-level است.
مثال پایه
typescriptimport { Component, OnInit } from '@angular/core';
import { Observable, of } from 'rxjs';
import { map, filter } from 'rxjs/operators';
@Component({
selector: 'app-rxjs-basic',
template: ` <h2>مثال عملگرهای RxJS</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);
}
}
در این مثال، کامپوننت RxjsBasicComponent نشان میدهد چگونه میتوان از Observables و عملگرهای پایه RxJS برای مدیریت دادهها در انگولار استفاده کرد. rawData$
یک Observable است که یک آرایه از اعداد را ارائه میدهد. عملگر filter
اطمینان حاصل میکند که آرایه خالی پردازش نمیشود و map
تنها اعداد زوج را استخراج میکند. subscribe
نتیجه پردازش شده را به property filteredData
اختصاص میدهد تا در template نمایش داده شود.
این پیادهسازی نشاندهنده تلفیق lifecycle hooks انگولار (ngOnInit
) با جریانهای دادهای ریاکتیو است. استفاده از Observable و operator pipeline باعث جلوگیری از prop drilling و re-render های غیرضروری میشود و pattern آن در پروژههای واقعی انگولار برای مدیریت دادههای API یا eventها کاربردی است. این مثال نشان میدهد چگونه میتوان state component را به شکل پیشبینیپذیر و maintainable مدیریت کرد.
مثال کاربردی
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>لیست کاربران</h2> <div *ngIf="loading">در حال بارگذاری داده...</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 = 'خطا در بارگذاری دادهها';
this.loading = false;
return of([]);
})
)
.subscribe(result => this.users = result);
}
}
Advanced انگولار 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="جستجوی محصول"> <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);
}
}
در این مثال پیشرفته، از BehaviorSubject و debounceTime برای ایجاد قابلیت جستجوی ریاکتیو استفاده شده است. switchMap تضمین میکند که تنها آخرین جستجو پردازش شود و catchError مدیریت خطاهای robust را فراهم میکند. جداسازی Service و Component باعث میشود state مرکزی مدیریت شود و component سبک و maintainable باقی بماند.
استفاده از async Pipe در template باعث میشود که subscriptionها به صورت خودکار مدیریت شوند و از memory leak جلوگیری شود. این الگو در پروژههای real-world SPAs برای performance و maintainability بهینه است. این پیادهسازی، ویژگیهای خاص انگولار مانند Dependency Injection، lifecycle hooks، و مدیریت ریاکتیو state را به خوبی نشان میدهد.
Best Practices و خطاهای رایج انگولار:
استفاده از عملگرهای RxJS در انگولار باید با حفظ clean و reusable بودن components همراه باشد. از Services برای مدیریت state استفاده کنید، از async Pipe برای binding مستقیم Observables در template بهره ببرید و side-effects را با tap مدیریت کنید. از prop drilling و re-render های غیرضروری اجتناب کنید.
اشتباهات رایج شامل تغییر مستقیم state، عدم مدیریت خطا در API calls، و استفاده نادرست از switchMap/mergeMap است. برای بهینهسازی عملکرد، از debounceTime و distinctUntilChanged استفاده کنید. امنیت و پایداری برنامه با catchError تضمین میشود و برای debugging میتوان از tap و Angular DevTools بهره برد.
📊 مرجع کامل
Operator | توضیح | Syntax | Example | Notes |
---|---|---|---|---|
map | تبدیل مقادیر Observable | observable.pipe(map(val => transform(val))) | of(1,2,3).pipe(map(x => x*2)) | برای تغییر state |
filter | فیلتر مقادیر | observable.pipe(filter(val => condition(val))) | of(1,2,3).pipe(filter(x => x>1)) | کنترل بروزرسانی UI |
switchMap | جایگزینی Observable قبلی | observable.pipe(switchMap(val => newObs)) | http.get('/api').pipe(switchMap(res => http.get('/api2'))) |
📊 Complete انگولار Properties Reference
Property | Values | Default | Description | انگولار Support |
---|---|---|---|---|
async | Observable | null | بایند مستقیم Observable در template | Angular 2+ |
BehaviorSubject | Subject | null | ذخیره و انتشار مقدار فعلی | Angular 2+ |
pipe | Function | – | ترکیب عملگرها | Angular 2+ |
subscribe | Function | – | شروع Observable | Angular 2+ |
tap | Function | – | اجرای side-effects | Angular 2+ |
catchError | Function | – | مدیریت خطا | Angular 6+ |
switchMap | Function | – | جایگزینی Observable | Angular 5+ |
mergeMap | Function | – | ادغام Observableها | Angular 5+ |
debounceTime | Number | 0 | تأخیر انتشار | Angular 5+ |
distinctUntilChanged | Function | – | جلوگیری از مقادیر تکراری | Angular 5+ |
shareReplay | Number | 1 | اشتراک و caching | Angular 5+ |
startWith | Value | – | مقدار اولیه | Angular 5+ |
خلاصه و گامهای بعدی:
یادگیری مرجع عملگرهای RxJS در انگولار، توانایی مدیریت جریان دادههای غیرهمزمان و ایجاد componentهای maintainable و performance-oriented را به توسعهدهنده میدهد. این مهارت پایهای برای طراحی برنامههای SPAs و enterprise-level است.
برای سطوح پیشرفته، آشنایی با عملگرهای exhaustMap، bufferTime و window و همچنین کتابخانههای مدیریت state مانند NgRx یا Akita توصیه میشود. استفاده درست از async Pipe، lifecycle hooks و error handling، عملکرد و پایداری برنامهها را تضمین میکند. تمرین مستمر، مطالعه documentation رسمی انگولار و RxJS و اجرای پروژههای واقعی بهترین روش برای تسلط کامل است.
🧠 دانش خود را بیازمایید
دانش خود را بیازمایید
خود را با این آزمون تعاملی به چالش بکشید و ببینید موضوع را چقدر خوب درک کردهاید
📝 دستورالعملها
- هر سوال را با دقت بخوانید
- بهترین پاسخ را برای هر سوال انتخاب کنید
- میتوانید آزمون را هر چند بار که میخواهید تکرار کنید
- پیشرفت شما در بالا نمایش داده میشود