Поиск по API отправляет запрос на каждую введённую строку. Ответы приходят в любом порядке: «lu» может прийти позже «luke» и перетереть правильную выдачу.
Напишите takeLatest(fetcher). fetcher(query, signal) возвращает промис. takeLatest возвращает функцию search(query) → промис. Каждый новый вызов search вызывает abort() у контроллера прошлого запроса и сразу отклоняет прошлый промис ошибкой с name === 'AbortError'.
Сервер может не уметь отменять запрос — тогда старый ответ всё равно придёт. Такой ответ надо проигнорировать. Ошибку последнего запроса (например, сеть) — пробросить как есть.
В работе: Живой поиск, подсказки адреса, переключение вкладок с загрузкой данных.
Пример 1: один запрос
[[0, "luke"]], {"luke": 200}, true{"aborted": [], "settled": [["luke", "ok", "результаты: luke", 200]], "started": [["luke", 0]]}Пример 2: набор по буквам
[[0, "l"], [100, "lu"], [150, "luk"]], {"l": 300, "lu": 300, "luk": 100}, true{"aborted": [["l", 100], ["lu", 150]], "settled": [["l", "fail", "AbortError", 100], ["lu", "fail", "AbortError", 150], ["luk", "ok", "результаты: luk", 250]], "started": [["l", 0], ["lu", 100], ["luk", 150]]}takeLatest — тест вызывает её сам. Таймеры и Date в тестах ненастоящие: время идёт по команде теста, поэтому setTimeout на 5 секунд проверяется мгновенно. Тестов 6: 2 открыты выше, остальные приходят после старта подхода. Лимит — 2 с на тест.
function takeLatest(fetcher) // → function search(query): Promise
Источник: обзор транскриптов интервью: Т‑Банк, компонент поиска по API с debounce и AbortController. Условие пересказано своими словами.
Ожидаемый ответ не нужен: покажем, что вернула функция.
Здесь появится результат отправки.