В КУРСЕ?

Разбираемся в теме

Поиск показывает старый ответ: как возникает гонка запросов во фронтенде

Пользователь меняет поисковую фразу, новый результат появляется на экране, а затем внезапно заменяется старым. Сервер мог ответить правильно на оба запроса. Ошибка возникает из-за того, что порядок получения ответов не совпал с порядком действий человека. Для устойчивого интерфейса важно хранить связь результата с актуальным запросом, а не просто показывать последний пришедший ответ.

Порядок отправки не задаёт порядок завершения

Представим два поиска в вымышленном каталоге: сначала лампа, затем лампа настольная. Первый запрос отправлен раньше, но обрабатывается дольше. Второй успевает завершиться первым. Если обработчик каждого ответа безусловно заменяет результаты, поздний ответ на короткую фразу перезапишет более подходящие данные. Здесь слово последний двусмысленно. Последним по времени поступления может оказаться ответ на уже устаревшее действие. Поэтому правило должно относиться к намерению пользователя: экран показывает результат текущего поиска. Для этого запрос связывают с идентификатором или другой однозначной отметкой актуальности. Проверку выполняют перед изменением состояния интерфейса.

Отмена и проверка актуальности решают связанные задачи

Ненужный запрос можно попытаться отменить. В браузерном интерфейсе для отменяемых операций применяется AbortController, который может остановить запрос fetch и обработку его ответа. Однако отмена не означает, что уже начавшаяся серверная работа обязательно обращена вспять. Наш пример касается чтения каталога, а не операций, изменяющих данные. Другой подход — игнорировать результат, если он больше не относится к текущему поиску. Это правило остаётся полезным и тогда, когда отмена недоступна или операция успела завершиться. Конкретная реализация зависит от используемых средств управления данными. Важен проверяемый итог: устаревший ответ не должен изменять ни список, ни сообщение об ошибке, ни состояние загрузки нового запроса.

Проверьте все состояния, а не только список

Допустим, новый поиск ещё выполняется, а старый завершился ошибкой. Если показать эту ошибку без проверки актуальности, человек решит, что не сработал текущий запрос. Похожая проблема возникает, когда старый обработчик выключает индикатор загрузки, хотя новая операция продолжается. Поэтому принадлежность запроса важна для каждого обновления состояния. Отдельно рассматривают уход со страницы, пустую фразу и повторный ввод одинакового текста. Не все эти случаи решаются одной проверкой строки: два одинаковых запроса могут относиться к разным моментам и условиям. Полезно сначала сформулировать ожидаемое поведение, затем моделировать неблагоприятный порядок событий. Быстрая сеть на компьютере разработчика часто скрывает ошибки, которые видны при разной длительности ответов.

Попробуйте на практике

Смоделируйте гонку двух запросов на бумаге, не подключаясь к реальному серверу.

  1. Создайте карточки первого и второго поиска с разными идентификаторами. Запишите правило: актуальным считается второй после его отправки.
  2. Расположите события так: отправлен первый, отправлен второй, получен второй ответ, получен первый. Покажите, какой список получился бы при безусловной замене.
  3. Примените проверку идентификатора перед каждым обновлением. Отдельно отметьте итоговые результаты и состояние загрузки после всех событий.
  4. Измените сценарий: первый запрос заканчивается ошибкой, пока второй ещё выполняется. Проверьте, что устаревшая ошибка не заменяет состояние нового поиска.

Как проверить результат. В обоих сценариях экран остаётся связан с актуальным запросом. Старый ответ или ошибка не перезаписывают новые данные и не завершают чужую загрузку. Правило можно объяснить независимо от скорости сети.

Частые вопросы

Достаточно ли задерживать отправку запроса после ввода?

Задержка может уменьшить количество запросов, но не гарантирует правильного порядка завершения уже отправленных. Проверка актуальности решает отдельную задачу.

Нужно ли всегда писать эту логику самостоятельно?

Нет. Средства загрузки и кэширования данных могут управлять частью поведения. Но разработчику всё равно нужно понимать их правила и проверять, что интерфейс соответствует текущему действию пользователя.

Самостоятельный разбор темы. Содержание конкретной обучающей программы здесь не представлено.

Зарегистрируйтесь, чтобы уточнить возможность доступа к этому материалу

Зарегистрироваться
← К списку материалов