Observable asoslari
Observable — vaqt o'tishi bilan nol yoki ko'p qiymat uzatadigan lazy asinxron oqim. Angular'da HTTP, Router, FormControl va event stream'lar Observable orqali ishlaydi.
Observable vs Promise — farqlari
Nima bu?
Promise — bitta qiymat (resolve yoki reject), darhol ishga tushadi (eager), cancel qilib bo'lmaydi. Observable — nol yoki ko'p qiymat, subscribe qilinganda ishga tushadi (lazy), unsubscribe bilan bekor qilinadi, operatorlar zanjiri (map, filter, switchMap) bilan boyitiladi. Angular HttpClient Observable qaytaradi — shuning uchun cancel, retry va stream boshqaruvi oson.
Kod misoli
import { Observable, from } from 'rxjs';
// Promise — bitta qiymat, ishga tushganda bajariladi
const promise = fetch('/api/user/1').then((r) => r.json());
// Cancel qilib bo'lmaydi
// Observable — lazy, subscribe qilganda ishlaydi
const obs$ = new Observable<number>((subscriber) => {
subscriber.next(1);
subscriber.next(2);
subscriber.complete();
});
const sub = obs$.subscribe((v) => console.log(v)); // 1, 2
sub.unsubscribe(); // to'xtatish mumkin
// Promise → Observable
from(fetch('/api/user/1').then((r) => r.json())).subscribe((user) => {
console.log(user.name);
});
Imtihonda
- HttpClient nima qaytaradi — Promise yoki Observable?
- Observable'ni qachon unsubscribe qilish kerak? Promise'da bu kerak emas — nega?
Yodlash uchun
Promise = 1 qiymat, eager, cancel yo'q. Observable = 0..N qiymat, lazy, cancel bor, operatorlar.
Cold vs Hot Observable
Nima bu?
Cold Observable — har bir subscriber o'z producer'ini ishga tushiradi (HttpClient, of(), from()). Ikki subscriber = ikki marta HTTP so'rov. Hot Observable — bitta producer, barcha subscriberlar bir xil oqimni oladi (DOM event, WebSocket, Subject). Subscribe qilgandan keyin kelgan qiymatlarni o'tkazib yuboradi. share(), shareReplay() cold'ni hot'ga aylantirish uchun ishlatiladi.
Kod misoli
import { interval, Subject, shareReplay } from 'rxjs';
import { HttpClient } from '@angular/common/http';
import { inject, Injectable } from '@angular/core';
@Injectable({ providedIn: 'root' })
export class UserService {
private http = inject(HttpClient);
// Cold — har subscriber alohida HTTP
getUserCold(id: number) {
return this.http.get(`/api/users/${id}`);
}
// Hot'ga aylantirish — bitta HTTP, ko'p subscriber
private config$ = this.http.get('/api/config').pipe(
shareReplay({ bufferSize: 1, refCount: true })
);
getConfig() {
return this.config$;
}
}
// Hot — Subject
const clicks$ = new Subject<MouseEvent>();
document.addEventListener('click', (e) => clicks$.next(e));
// Cold — interval (har subscriber alohida sanaydi)
const cold$ = interval(1000);
cold$.subscribe((n) => console.log('A:', n));
cold$.subscribe((n) => console.log('B:', n)); // A va B har xil raqam
Imtihonda
- HttpClient cold yoki hot? Ikki component bir xil GET'ga subscribe qilsa nima bo'ladi?
- Hot Observable'ga kech subscribe qilsa nima bo'ladi?
Yodlash uchun
Cold = har subscriber alohida producer. Hot = bitta manba, kech kelganlar eski qiymatlarni ko'rmaydi (ReplaySubject bundan mustasno).
Yaratish — of, from, interval, timer, fromEvent
Nima bu?
RxJS Observable yaratishning bir necha usuli: of() — sinxron qiymat(lar); from() — Promise, array yoki iterable; interval(ms) — har N ms da raqam; timer(delay, period) — kechikish + interval; fromEvent(target, event) — DOM yoki Node event stream. Angular'da form eventlari va custom Subject'lar ham keng ishlatiladi.
Kod misoli
import { of, from, interval, timer, fromEvent } from 'rxjs';
import { map, take } from 'rxjs/operators';
// of — darhol qiymatlar
of(1, 2, 3).subscribe(console.log);
// from — array yoki Promise
from([10, 20, 30]).pipe(map((x) => x * 2)).subscribe(console.log);
from(fetch('/api/data').then((r) => r.json())).subscribe(console.log);
// interval — polling simulyatsiyasi
interval(2000).pipe(take(5)).subscribe((n) => console.log('tick', n));
// timer — 3s kutib, keyin har 1s
timer(3000, 1000).pipe(take(3)).subscribe(console.log);
// fromEvent — Angular template'da (Renderer2) yoki:
const input$ = fromEvent<KeyboardEvent>(document, 'keyup');
input$.pipe(
map((e) => (e.target as HTMLInputElement).value)
).subscribe(console.log);
Imtihonda
interval(1000)vatimer(0, 1000)farqi nima?- Promise'dan Observable yaratish uchun qaysi operator?
Yodlash uchun
of = qiymat; from = iterable/Promise; interval = darhol boshlanadi; timer = kechikish bilan.
subscribe — next, error, complete
Nima bu?
subscribe() Observable'ni ishga tushiradi. next — har yangi qiymat; error — xato (stream tugaydi); complete — muvaffaqiyatli tugash. Ob'ekt sintaksisi yoki alohida callback'lar ishlatiladi. HttpClient odatda bitta next + complete yoki error qaytaradi. Infinite stream (interval) complete bo'lmaydi — faqat unsubscribe yoki take(n) bilan to'xtatiladi.
Kod misoli
import { Observable, throwError } from 'rxjs';
const stream$ = new Observable<number>((subscriber) => {
subscriber.next(1);
subscriber.next(2);
subscriber.error(new Error('Xato yuz berdi'));
subscriber.next(3); // error'dan keyin ishlamaydi
});
// Ob'ekt sintaksisi (tavsiya etiladi)
stream$.subscribe({
next: (value) => console.log('Qiymat:', value),
error: (err) => console.error('Xato:', err.message),
complete: () => console.log('Tugadi'),
});
// HttpClient misoli
this.http.get<User[]>('/api/users').subscribe({
next: (users) => (this.users = users),
error: (err) => (this.errorMessage = err.message),
complete: () => console.log('So\'rov muvaffaqiyatli'),
});
Imtihonda
- Error yuz berganda complete chaqiriladimi?
subscribe()qaytargan ob'ekt nima uchun kerak?
Yodlash uchun
Error yoki complete — stream tugaydi. Subscription ob'ekti unsubscribe() uchun.
unsubscribe — xotira tozalash
Nima bu?
Component destroy bo'lganda ochiq subscription'lar xotira sızıntısı (memory leak) va keraksiz HTTP so'rovlariga olib keladi. subscription.unsubscribe() yoki takeUntil(destroy$) bilan tozalash kerak. HttpClient so'rovlari complete bo'lganda o'zi yopiladi, lekin interval, Router eventlari, Subject'lar — doim tozalash talab qiladi. Angular 16+ da takeUntilDestroyed() avtomatik qiladi.
Kod misoli
import { Component, OnDestroy, OnInit } from '@angular/core';
import { Subject, Subscription, interval } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
@Component({ /* ... */ })
export class TimerComponent implements OnInit, OnDestroy {
private destroy$ = new Subject<void>();
private sub?: Subscription;
ngOnInit() {
// Usul 1: Subscription saqlash
this.sub = interval(1000).subscribe((n) => (this.count = n));
// Usul 2: takeUntil (tavsiya)
interval(1000)
.pipe(takeUntil(this.destroy$))
.subscribe((n) => (this.count = n));
}
ngOnDestroy() {
this.sub?.unsubscribe();
this.destroy$.next();
this.destroy$.complete();
}
}
Imtihonda
- Qaysi stream'larda unsubscribe shart?
takeUntilva qo'ldaunsubscribefarqi nima?
Yodlash uchun
Uzoq yashovchi stream = unsubscribe shart. HttpClient bitta javob = odatda OK.
