BACK
Уроки43. scan: состояние как накопление
Уроки · 43

43. scan: состояние как накопление

scan — reduce во времени

Если знакомы с Array.prototype.reducescan работает почти так же, но с одним важным отличием: он эмитит промежуточный результат после каждого значения, а не только финальный.

from([1, 1, -1, 1]).pipe(scan((acc, x) => acc + x, 0))
// 0+1=1 → next(1)
// 1+1=2 → next(2)
// 2-1=1 → next(1)
// 1+1=2 → next(2)

Почему это очень мощно

Состояние в UI часто рождается из последовательности событий: клик «плюс» → +1, клик «минус» → −1, добавили todo → новый элемент в списке. scan превращает поток событий в поток состояний.

Сигнатура

scan(reducer, seed):

  • reducer(acc, value) => newAcc — функция, которая получает аккумулятор и значение, возвращает новый аккумулятор.
  • seed — начальное значение аккумулятора.

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

  1. В pipe добавьте scan((count, change) => count + change, 0).
  2. Ожидаемый вывод: Count: 1 → Count: 2 → Count: 1 → Count: 2.
Решение spoiler · click to reveal
const { from, scan } = Rx;

const changes$ = from([1, 1, -1, 1]);

const count$ = changes$.pipe(
  scan((count, change) => count + change, 0)
);

count$.subscribe(value => console.log('Count: ' + value));
script.ts // TypeScript
CONSOLE · Console Output
Нажмите на запуск, чтобы увидеть результат...