Subject turlari
Subject — ham Observable ham Observer. Hot stream yaratish, component'lar orasida event uzatish va service'da state saqlash uchun Angular'da keng qo'llaniladi.
Subject — sodda, hot observable
Nima bu?
Subject — multicast hot Observable. .next(), .error(), .complete() bilan qiymat yuborish mumkin. Subscribe qilgandan keyin kelgan qiymatlarni oladi — oldingi qiymatlar yo'q. Event bus, component'dan service'ga signal va oddiy pub/sub pattern uchun.
Kod misoli
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';
@Injectable({ providedIn: 'root' })
export class NotificationService {
private notificationSubject = new Subject<string>();
// Faqat o'qish — tashqaridan next qilib bo'lmaydi
notifications$ = this.notificationSubject.asObservable();
push(message: string) {
this.notificationSubject.next(message);
}
}
// Component
this.notificationService.notifications$.subscribe((msg) => {
this.toast.show(msg);
});
// Subscribe qilishdan OLDIN
service.push('Birinchi'); // yangi subscriber ko'rmaydi
const sub = service.notifications$.subscribe(console.log);
service.push('Ikkinchi'); // ✅ ko'radi
Imtihonda
- Subject cold yoki hot?
asObservable()nima uchun kerak?
Yodlash uchun
Subject = hot, oxirgi qiymat saqlanmaydi. asObservable() = faqat subscribe, next yashirin.
BehaviorSubject — oxirgi qiymat saqlanadi
Nima bu?
BehaviorSubject — dastlabki qiymat (seed) bilan yaratiladi va oxirgi qiymatni saqlaydi. Yangi subscriber darhol oxirgi qiymatni oladi. Angular service'larda current user, theme, cart state va value/getValue() orqali sinxron o'qish uchun eng ko'p ishlatiladi.
Kod misoli
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
import { map } from 'rxjs/operators';
interface CartItem {
id: number;
qty: number;
}
@Injectable({ providedIn: 'root' })
export class CartService {
private cartSubject = new BehaviorSubject<CartItem[]>([]);
cart$ = this.cartSubject.asObservable();
totalItems$ = this.cart$.pipe(
map((items) => items.reduce((sum, i) => sum + i.qty, 0))
);
addItem(item: CartItem) {
const current = this.cartSubject.getValue();
this.cartSubject.next([...current, item]);
}
// Sinxron o'qish
get snapshot(): CartItem[] {
return this.cartSubject.getValue();
}
}
// Yangi subscriber darhol [] yoki oxirgi cart oladi
cartService.cart$.subscribe(console.log);
Imtihonda
- BehaviorSubject va Subject farqi?
- Angular'da state uchun nima uchun BehaviorSubject, oddiy Subject emas?
Yodlash uchun
BehaviorSubject = seed + oxirgi qiymat + yangi subscriber darhol oladi. State store klassikasi.
ReplaySubject(n) — oxirgi n ta saqlanadi
Nima bu?
ReplaySubject(bufferSize) — oxirgi n ta qiymatni buffer'da saqlaydi. Kech subscribe qilganlar ham so'nggi n ta qiymatni oladi. Chat history, so'nggi N ta log, yoki HTTP cache (shareReplay ichida) uchun. refCount: true bilan barcha subscriber ketganda tozalanadi.
Gotcha: bufferSize bermasdan new ReplaySubject() yaratilsa, u cheksiz qiymatni xotirada saqlaydi — uzoq ishlaydigan Subject'da (masalan, global event bus) bu asta-sekin xotira sızıntısiga aylanadi. Ikkinchi argument windowTime (ms) bilan vaqt bo'yicha ham cheklash mumkin — new ReplaySubject(10, 5000) faqat oxirgi 5s ichidagi (max 10 ta) qiymatni saqlaydi.
Kod misoli
import { ReplaySubject } from 'rxjs';
import { shareReplay } from 'rxjs/operators';
// Oxirgi 3 ta xabar
const chat$ = new ReplaySubject<string>(3);
chat$.next('Salom');
chat$.next('Qalaysiz?');
chat$.next('Yaxshi');
chat$.next('Rahmat');
chat$.subscribe((msg) => console.log('User A:', msg)); // Qalaysiz?, Yaxshi, Rahmat
// shareReplay — HTTP uchun
@Injectable({ providedIn: 'root' })
export class ConfigService {
config$ = this.http.get<AppConfig>('/api/config').pipe(
shareReplay({ bufferSize: 1, refCount: true })
);
}
Imtihonda
- ReplaySubject(1) va BehaviorSubject farqi?
- shareReplay(1) qachon ishlatiladi?
Yodlash uchun
ReplaySubject(n) = oxirgi n ta replay. shareReplay(1) = HTTP cache pattern.
AsyncSubject — faqat complete'dagi
Nima bu?
AsyncSubject — faqat complete bo'lganda oxirgi bitta qiymatni subscriber'larga beradi. .next() lar saqlanadi, complete'da faqat oxirgisi emit qilinadi. Error bo'lsa hech narsa bermaydi. Kam ishlatiladi — odatda Promise-like pattern yoki test'larda uchraydi. Amaliy Angular kodida BehaviorSubject yoki firstValueFrom ko'proq.
Kod misoli
import { AsyncSubject } from 'rxjs';
const subject = new AsyncSubject<number>();
subject.subscribe((v) => console.log('A:', v));
subject.next(1);
subject.next(2);
subject.next(3);
subject.complete(); // A: 3 (faqat oxirgi)
// Error — hech kim olmaydi
const errSubject = new AsyncSubject<string>();
errSubject.subscribe({ next: console.log, error: console.error });
errSubject.next('data');
errSubject.error(new Error('fail'));
Imtihonda
- AsyncSubject qachon qiymat emit qiladi?
- To'rtta Subject turini taqqoslang.
Yodlash uchun
AsyncSubject = complete → oxirgi 1 ta. Subject, BehaviorSubject, ReplaySubject kundalik ishda.
