BACK
Уроки46. Effects pattern: actions in, async work out
Уроки · 46

46. Effects pattern: actions in, async work out

Что такое effect

Если scan превращает actions в state, то effect делает другое: actions → побочная работа (HTTP, таймер, сохранение) → новые actions. Это вторая половина паттерна Redux/NgRx Effects.

actions$.pipe(
  filter(a => a.type === 'save'),
  concatMap(a => api.save(a).pipe(map(() => ({ type: 'saved', id: a.id }))))
)

Почему concatMap для сохранений

Сохранения нельзя перемешивать. Если запустить два save через mergeMap, и второй закончится раньше, то старый ответ может перезаписать новое состояние на сервере. concatMap ставит их в очередь — это безопасно.

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

  1. В pipe сначала filter(action => action.type === 'save').
  2. Через запятую concatMap(action => timer(20).pipe(map(() => ({ type: 'saved', id: action.id })))).
  3. Action ignore отфильтруется, останутся два сохранения.

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

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

Решение spoiler · click to reveal
const { Subject, timer, filter, concatMap, map } = Rx;

const actions$ = new Subject();

const effect$ = actions$.pipe(
  filter(action => action.type === 'save'),
  concatMap(action => {
    return timer(20).pipe(
      map(() => ({ type: 'saved', id: action.id }))
    );
  })
);
script.ts // TypeScript
CONSOLE · Console Output
Нажмите на запуск, чтобы увидеть результат...