Уроки43. scan: состояние как накопление
Уроки · 43
43. scan: состояние как накопление
scan — reduce во времени
Если знакомы с Array.prototype.reduce — scan работает почти так же, но с одним важным отличием: он эмитит промежуточный результат после каждого значения, а не только финальный.
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— начальное значение аккумулятора.
Что нужно сделать
- В
pipeдобавьтеscan((count, change) => count + change, 0). - Ожидаемый вывод:
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
CONSOLE · Console Output
Нажмите на запуск, чтобы увидеть результат...