Реактивное программирование и RxJS (обзорно)
↑ 8.1 Парадигмы: ООП, ФП, SOLID · ← Предыдущая
Зачем это на собесе
Достаточно понимать идею потоков, ключевые операторы и отличие от Promise; RxJS часто встречается в Angular и сложных сценариях.
Идея
Данные — потоки событий во времени. Подписываемся и реагируем, комбинируя потоки операторами.
Observable vs Promise
| Promise | Observable | |
|---|---|---|
| Значений | одно | ноль, одно или много |
| Выполнение | сразу (eager) | ленивое, при подписке |
| Отмена | нет (AbortController) | unsubscribe() |
| Операторы | then/catch | десятки (map, switchMap, debounceTime) |
Пример: поиск
import { fromEvent, debounceTime, map, distinctUntilChanged, switchMap, catchError, of } from 'rxjs'
import { ajax } from 'rxjs/ajax'
const sub = fromEvent<InputEvent>(input, 'input').pipe(
map(e => (e.target as HTMLInputElement).value.trim()),
debounceTime(300),
distinctUntilChanged(),
switchMap(q => ajax.getJSON(`/api/search?q=${q}`).pipe(catchError(() => of([])))),
).subscribe(render)
// sub.unsubscribe() при размонтированииswitchMap отменяет предыдущий запрос при новом значении — решает гонки запросов.
Основные операторы
| Категория | Операторы |
|---|---|
| Преобразование | map, scan, pluck |
| Фильтрация | filter, take, debounceTime, distinctUntilChanged |
| Комбинирование | combineLatest, merge, zip, withLatestFrom |
| Высшего порядка | switchMap, mergeMap, concatMap, exhaustMap |
| Ошибки | catchError, retry |
Выбор: switchMap — только последнее (поиск), concatMap — по очереди, mergeMap — параллельно, exhaustMap — игнорировать, пока идёт (кнопка «отправить»).
Subjects и Hot/Cold
Subject,BehaviorSubject(хранит текущее значение),ReplaySubject;- cold: каждый подписчик запускает своё выполнение (HTTP);
- hot: общий источник (события),
share(),shareReplay(1).
Во Vue
Vue использует свои refs. Для RxJS: @vueuse/rxjs (useObservable, useSubscription), либо watch + debounce + AbortController для простых задач.
Утечки
Всегда отписывайтесь (takeUntil, unsubscribe, takeUntilDestroyed). Незавершённые подписки — классическая утечка.
Вопросы с ответами
Когда RxJS оправдан, а когда хватит Promise?
Для сложных потоков: автоподстановка, комбинирование источников, WebSocket, отмена, повтор. Для одиночного запроса достаточно
fetchиasync/await.
Разница между switchMap и mergeMap?
switchMapотменяет предыдущий внутренний поток при новом значении,mergeMapзапускает все параллельно.