IslomDevIslomDev
Booster
Imtihon
Booster
Imtihon
  • Angular Intervyu Tayyorgarlik
  • JavaScript / TypeScript

    • JavaScript / TypeScript
    • Asoslar (JavaScript)
    • Asinxronlik
    • Prototip va OOP
    • TypeScript
    • Performance
  • Algoritmlash

    • Algoritmlash
    • Murakkablik tahlili
    • Ma'lumot tuzilmalari
    • Qidiruv va Saralash
    • Algoritmik paradigmalar
    • Amaliy masalalar
  • Angular — Boshlang'ich

    • Angular — Boshlang'ich
    • Component
    • Template
    • Change Detection
    • Advanced Component
  • Angular — Service va DI

    • Angular — Service va DI
    • Service asoslari
    • HTTP
    • Hierarchical DI
    • Advanced DI
    • State management (service)
  • Angular — Versiyalar

    • Angular — Versiyalar
    • Angular 12–13
    • Angular 14
    • Angular 15
    • Angular 16
    • Angular 17
    • Angular 18+
  • Angular — Directive

    • Angular — Directive
    • Built-in Directives
    • Custom Attribute Directive
    • Custom Structural Directive
    • Advanced
  • Angular — RxJS

    • Angular — RxJS
    • Observable asoslari
    • Asosiy operatorlar
    • Higher-order operatorlar
    • Combination operatorlar
    • Subject turlari
    • Xato va xotira
    • Advanced
  • Angular — Pipe

    • Angular — Pipe
    • Built-in Pipes
    • Custom Pipe
    • Performance
  • Angular — Forms

    • Angular — Forms
    • Template-driven Forms
    • Reactive Forms
    • Validators
    • Advanced
  • Angular — NgModule

    • Angular — NgModule
    • NgModule asoslari
    • Module arxitekturasi
    • Lazy Loading
    • Standalone vs NgModule
  • Angular — Sintaksis va Clean Code

    • Angular — Sintaksis va Clean Code
    • Template sintaksisi
    • Angular 17+ yangi sintaksis
    • Komponent arxitekturasi
    • Performance pattern'lar
    • SOLID va Clean Code
    • Testing

Combination operatorlar

Daraja:

Combination operatorlar bir nechta Observable'ni birlashtiradi — parallel HTTP, form field'larni birga kuzatish va bir stream boshqa stream'ning oxirgi qiymatini olish uchun.

combineLatest — istalgan biri o'zgarganda

Middle

Nima bu?

combineLatest — bir nechta Observable'ning har biri kamida bir marta emit qilgach, istalgan biri o'zgarganda barcha oxirgi qiymatlarni massiv (yoki ob'ekt) sifatida emit qiladi. Filter formasi (category + price + sort), dashboard widget'lar va bir nechta FormControl'ni birga kuzatish uchun ideal.

Kod misoli

import { combineLatest } from 'rxjs';
import { map, startWith } from 'rxjs/operators';

@Component({ /* ... */ })
export class ProductFilterComponent {
  categoryCtrl = new FormControl('all');
  minPriceCtrl = new FormControl(0);
  sortCtrl = new FormControl('name');

  filteredProducts$ = combineLatest([
    this.categoryCtrl.valueChanges.pipe(startWith('all')),
    this.minPriceCtrl.valueChanges.pipe(startWith(0)),
    this.sortCtrl.valueChanges.pipe(startWith('name')),
  ]).pipe(
    map(([category, minPrice, sort]) => ({ category, minPrice, sort })),
    switchMap((filters) => this.api.getProducts(filters))
  );
}

// Ob'ekt sintaksisi — nomli field'lar
combineLatest({
  user: this.auth.user$,
  permissions: this.auth.permissions$,
  theme: this.settings.theme$,
}).subscribe(({ user, permissions, theme }) => {
  this.render(user, permissions, theme);
});

Imtihonda

  • combineLatest va forkJoin farqi nima?
  • Nima uchun startWith kerak bo'ladi?

Yodlash uchun

combineLatest = istalgan o'zgarish → barcha oxirgi qiymatlar. startWith — birinchi emit uchun.

FormControl valueChanges birinchi subscribe'da emit qilmaydi — startWith yoki form.value bilan boshlang.

forkJoin — barchasi tugaganda (parallel HTTP)

Middle

Nima bu?

forkJoin — bir nechta Observable'ni parallel ishga tushiradi va hammasi complete bo'lganda bitta emit qiladi (Promise.all ga o'xshash). Dashboard yuklash, detail page (user + orders + settings) va bir martalik parallel fetch uchun. Bittasi error bo'lsa butun forkJoin error. Faqat complete bo'ladigan stream'lar uchun — infinite stream ishlamaydi.

Kod misoli

import { forkJoin } from 'rxjs';
import { map } from 'rxjs/operators';

@Component({ /* ... */ })
export class DashboardComponent implements OnInit {
  dashboard$ = forkJoin({
    user: this.http.get<User>('/api/me'),
    stats: this.http.get<Stats>('/api/stats'),
    notifications: this.http.get<Notification[]>('/api/notifications'),
  });

  ngOnInit() {
    this.dashboard$.subscribe({
      next: ({ user, stats, notifications }) => {
        this.user = user;
        this.stats = stats;
        this.notifications = notifications;
      },
      error: (err) => this.handleError(err),
    });
  }
}

// Array sintaksisi
forkJoin([
  this.http.get('/api/a'),
  this.http.get('/api/b'),
]).pipe(map(([a, b]) => ({ a, b })));

Imtihonda

  • forkJoin va combineLatest qachon ishlatiladi?
  • forkJoin infinite stream (interval) bilan ishlaydimi?

Yodlash uchun

forkJoin = parallel + hammasi tugaganda (Promise.all). combineLatest = istalgan o'zgarishda.

zip, merge, concat

MiddleSenior

Nima bu?

zip — har stream'dan navbatma-navbat bitta qiymat oladi (1-chi + 1-chi, 2-chi + 2-chi). Eng qisqa stream tugaganda to'xtaydi. merge — barcha stream'larni bitta oqimga aralashtiradi, kelish tartibida. concat — birinchi stream tugagach ikkinchisini boshlaydi (concatMap ga o'xshash, lekin stream darajasida).

Gotcha: agar bitta stream boshqasidan doim tezroq emit qilsa, zip tez stream'ning qiymatlarini ichki bufferda ushlab turadi (juftini kutadi) — cheksiz tez interval bilan sekin HTTP javobni zip qilish xotira sizib chiqishiga olib kelishi mumkin. merge va concatda esa bittasi error qaytarsa — butun kombinatsiya darhol error bilan tugaydi, qolgan stream'lar (hali complete bo'lmagan bo'lsa ham) unsubscribe qilinadi — bu forkJoin'dagi xatti-harakatga o'xshaydi, lekin combineLatest'dan farqli, chunki combineLatest ham xato kelganda darhol to'xtaydi.

Kod misoli

import { of, interval } from 'rxjs';
import { zip, merge, concat, take, map } from 'rxjs';

// zip — juftlash
zip(of('A', 'B', 'C'), of(1, 2, 3)).subscribe(console.log);
// ['A', 1], ['B', 2], ['C', 3]

// merge — aralashtirish
merge(
  of('a', 'b').pipe(delay(100)),
  of(1, 2).pipe(delay(50))
).subscribe(console.log); // 1, 2, a, b (vaqt bo'yicha)

// concat — ketma-ket
concat(
  this.http.get('/api/step1'),
  this.http.get('/api/step2')
).subscribe(); // step1 tugagach step2

Imtihonda

  • zip va combineLatest farqi?
  • concat va forkJoin farqi?

Yodlash uchun

zip = juft (index bo'yicha). merge = aralashtir. concat = ketma-ket stream.

withLatestFrom

MiddleSenior

Nima bu?

withLatestFrom — asosiy (trigger) stream emit qilganda, boshqa stream'larning oxirgi qiymatini oladi va juft emit qiladi. Button click + form qiymati, save click + oxirgi filter holati kabi holatlarda — trigger faqat bir stream'dan, kontekst boshqalardan.

Gotcha: agar hamrohlik qiluvchi (masalan, form.valueChanges) stream hali birorta ham qiymat emit qilmagan bo'lsa, withLatestFrom trigger kelganda ham hech narsa emit qilmaydi — shuning uchun yuqoridagi misolda startWith(this.form.value) shart, aks holda birinchi save click "yo'qolib qoladi". Bu — kombinatsiya operatorlarida eng ko'p uchraydigan silent bug.

Kod misoli

import { fromEvent } from 'rxjs';
import { withLatestFrom, map } from 'rxjs/operators';

@Component({
  template: `
    <form [formGroup]="form">
      <input formControlName="email" />
      <button #saveBtn type="button">Saqlash</button>
    </form>
  `,
})
export class ProfileComponent {
  form = new FormGroup({
    email: new FormControl(''),
    name: new FormControl(''),
  });

  ngAfterViewInit() {
    fromEvent(this.saveBtn.nativeElement, 'click')
      .pipe(
        withLatestFrom(this.form.valueChanges.pipe(startWith(this.form.value))),
        map(([, formValue]) => formValue),
        exhaustMap((value) => this.api.saveProfile(value))
      )
      .subscribe();
  }
}

// combineLatest vs withLatestFrom:
// combineLatest — har qandasi o'zgarganda emit
// withLatestFrom — faqat click (trigger) bo'lganda, form oxirgi qiymati bilan

Imtihonda

  • Save button + form value — combineLatest yoki withLatestFrom?
  • withLatestFrom'da trigger stream qaysi?

Yodlash uchun

withLatestFrom = trigger + boshqalarning oxirgi qiymati. Birinchi argument — trigger.

Prev
Higher-order operatorlar
Next
Subject turlari