Уроки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 не помог, возвращаем безопасную строку.
Что нужно сделать
- В функции
liveSearchзаполнитеsource$.pipe(...)— см. полную цепочку выше. - Marble-тест: запрос
rотменится debounce'ом,rxуспешно вернётResult: rx,badупадёт, retry попробует ещё раз — снова упадёт — catchError вернётFallback: bad. - Проверка убедится, что
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
CONSOLE · Console Output
Нажмите на запуск, чтобы увидеть результат...