BACK
Уроки29. combineLatest: последние значения всех источников
Уроки · 29

29. combineLatest: последние значения всех источников

combineLatest — собрать состояние из частей

combineLatest([a$, b$, c$]) подписывается на несколько источников и хранит «последнее значение каждого». Как только каждый хотя бы раз что-то выдал, начинает работать так: при любом новом значении от любого источника он эмитит массив [lastA, lastB, lastC].

price$:   100 ────────────────
count$:   ──────── 3 ──── 5
result$:  ─────── [100,3] [100,5]

Где это встречается

Любое UI-состояние, собранное из нескольких независимых источников: поисковый запрос + категория + сортировка, цена + количество, форма + права пользователя.

Главная ловушка

Если хотя бы один источник никогда ничего не выдал, combineLatest будет молчать. Часто эту проблему решают через startWith на каждом источнике, чтобы дать им стартовое значение.

Деструктуризация массива

Массив [price, count] в map удобно сразу распаковать через деструктуризацию: map(([price, count]) => ...).

Что нужно сделать

  1. В combineLatest([price$, count$]).pipe(...) добавьте map(([price, count]) => 'Total: ' + price * count).
  2. Когда count$ выдаст значение через 20мс, выйдет одна строка Total: 300.

Детерминированная проверка

В этой задаче проверка идет через виртуальное время TestScheduler. Если решение верное, в консоли появится только Test Passed!. Не добавляйте лишние console.log, иначе проверка провалится.

Решение spoiler · click to reveal
const { of, timer, combineLatest, map } = Rx;

const price$ = of(100);
const count$ = timer(20).pipe(map(() => 3));

const total$ = combineLatest([price$, count$]).pipe(
  map(([price, count]) => 'Total: ' + price * count)
);
script.ts // TypeScript
CONSOLE · Console Output
Нажмите на запуск, чтобы увидеть результат...