BACK
Уроки25. switchMap: последний запрос побеждает
Уроки · 25

25. switchMap: последний запрос побеждает

switchMap — последний побеждает

switchMap ведёт себя иначе: при появлении нового внешнего значения он отменяет текущий внутренний Observable (если тот ещё работает) и запускает новый.

входы:  'a' → 'an' → 'angular'
switchMap: запрос(a) → отмена → запрос(an) → отмена → запрос(angular) → результат

Главный сценарий — typeahead

Пользователь печатает в поиске. Каждый промежуточный запрос (для «a», «an») уже не нужен — нужен только последний. switchMap бесплатно даёт «отмену устаревших запросов», что особенно ценно для HTTP в Angular.

Сводка четырёх операторов

  • mergeMap — параллельно, порядок не важен.
  • concatMap — очередь, строгий порядок.
  • switchMap — отменяем старое, оставляем новое.
  • exhaustMap (следующий урок) — игнорируем новое, пока старое работает.

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

  1. В pipe добавьте switchMap(value => timer(50).pipe(map(() => 'Done ' + value))).
  2. Источник выдаёт 0, 1, 2 каждые 20мс, но внутренний таймер длится 50мс. Значит, пока считается 0, приходит 1 — старый отменяется.
  3. До результата дойдёт только последнее значение 2.

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

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

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

const source$ = hot('a 19ms b 19ms c|', {
  a: 0,
  b: 1,
  c: 2,
});

const result$ = source$.pipe(
  switchMap(value => {
    return timer(50).pipe(
      map(() => 'Done ' + value)
    );
  })
);
script.ts // TypeScript
CONSOLE · Console Output
Нажмите на запуск, чтобы увидеть результат...