BACK
Уроки56. Final exam: liveSearch operator
Уроки · 56

56. Final exam: liveSearch operator

Финальный экзамен — production-grade liveSearch

Поздравляем — это последний урок курса. Здесь мы соберём всё вместе: операторы для управления потоком, обработку ошибок, повторные попытки, fallback. Получится оператор, который реально готов работать в production.

Полная цепочка

function liveSearch(searchApi) {
  return source$ => source$.pipe(
    debounceTime(20),         // ждём паузу в наборе
    distinctUntilChanged(),   // отсекаем повторы
    switchMap(query =>
      searchApi(query).pipe(  // внутренний запрос
        retry(1),             // одна повторная попытка
        catchError(() => of('Fallback: ' + query))  // последняя линия защиты
      )
    )
  );
}

Почему именно так

  • retry и catchError стоят внутри switchMap — это критически важно. Если их вынести наружу, ошибка одного запроса убьёт весь поток поиска навсегда.
  • retry(1) — одна повторная попытка для случайных сбоев сети.
  • catchError — последняя страховка: если retry не помог, возвращаем безопасную строку.

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

  1. В функции liveSearch заполните source$.pipe(...) — см. полную цепочку выше.
  2. Marble-тест: запрос r отменится debounce'ом, rx успешно вернёт Result: rx, bad упадёт, retry попробует ещё раз — снова упадёт — catchError вернёт Fallback: bad.
  3. Проверка убедится, что bad вызвал ровно 2 попытки.

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

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

Решение spoiler · click to reveal
const { of, defer, debounceTime, distinctUntilChanged, switchMap, retry, catchError } = Rx;

function liveSearch(searchApi) {
  return source$ => source$.pipe(
    debounceTime(20),
    distinctUntilChanged(),
    switchMap(query => {
      return searchApi(query).pipe(
        retry(1),
        catchError(() => of('Fallback: ' + query))
      );
    })
  );
}
script.ts // TypeScript
CONSOLE · Console Output
Нажмите на запуск, чтобы увидеть результат...