Основы реактивного программирования

Angular тесно интегрирован с библиотекой RxJS, что делает реактивное программирование фундаментальным для современных приложений. Реактивное программирование позволяет описывать поток данных, реагирующий на изменения во времени, без явного управления состоянием через DOM.

Observable и поток данных

Основной строительный блок реактивного подхода — Observable:

import { Observable } from 'rxjs';

const data$: Observable<number> = new Observable(subscriber => {
  subscriber.next(1);
  subscriber.next(2);
  setTimeout(() => subscriber.next(3), 1000);
});
  • Observable — источник данных, который может эмитировать значения с течением времени.
  • Метод subscribe позволяет подписаться на эти значения:
data$.subscribe(value => console.log(value));

Операторы трансформации

RxJS предоставляет множество операторов для работы с потоками данных:

  • map — трансформация значения:
import { map } from 'rxjs/operators';

data$.pipe(map(value => value * 2))
       .subscribe(console.log);
  • filter — фильтрация значений:
import { filter } from 'rxjs/operators';

data$.pipe(filter(value => value > 1))
       .subscribe(console.log);
  • merge и combineLatest — объединение нескольких потоков в один.

Асинхронные данные и HttpClient

Angular HttpClient возвращает Observable, что позволяет обрабатывать асинхронные данные в реактивном стиле:

this.http.get<User[]>('/api/users')
  .pipe(
    map(users => users.filter(user => user.active))
  )
  .subscribe(activeUsers => this.activeUsers = activeUsers);

Субъекты (Subject) и управление состоянием

Subject — это одновременно источник и подписчик, что делает его удобным для шаринга состояний между компонентами:

import { Subject } from 'rxjs';

const subject = new Subject<number>();
subject.subscribe(value => console.log('Подписка 1:', value));
subject.subscribe(value => console.log('Подписка 2:', value));

subject.next(1);
subject.next(2);
  • BehaviorSubject хранит текущее значение и сразу отдает его новым подписчикам.
  • ReplaySubject хранит несколько последних значений.
  • AsyncSubject эмитирует только последнее значение после завершения потока.

Интеграция с Angular Forms

Реактивные формы полностью построены на Observable, что позволяет динамически отслеживать изменения:

this.form.get('email')!.valueChanges
    .pipe(
        filter(value => value.includes('@')),
        debounceTime(300)
    )
    .subscribe(validEmail => console.log(validEmail));

Здесь:

  • valueChanges — поток изменений поля.
  • debounceTime — задержка для предотвращения частых эмиттов.
  • filter — фильтрует значения до заданного условия.

Управление потоками с async pipe

Использование async pipe в шаблонах позволяет подписываться на Observable без явного вызова subscribe, автоматически управляя подпиской:

<div *ngIf="users$ | async as users">
  <div *ngFor="let user of users">{{ user.name }}</div>
</div>

Такой подход снижает вероятность утечек памяти и упрощает код компонентов.


Эти два аспекта — временные функции анимаций и основы реактивного программирования — являются базой для создания динамичных и отзывчивых интерфейсов в Angular, сочетая визуальную выразительность и управление потоками данных в единой архитектуре.