Веб-версияОткрыть в Telegram

ПостПочему старый fetch-запрос может перезаписать новый?

18 сентября 2026
C
Code Ready | Frontend
Почему старый fetch-запрос может перезаписать новый? Асинхронные операции завершаются независимо от порядка запуска. Поэтому в интерфейсах, где новый запрос делает предыдущий результат неактуальным, может возникнуть race condition. Например, пользователь быстро продолжает вводить поисковый запрос. Запрос для более длинной и актуальной строки может завершиться раньше предыдущего. Если каждый ответ безусловно передавать в renderResults(), более старый результат в итоге перезапишет актуальный: search.addEventListener('input', async event => { const query = encodeURIComponent(event.target.value); const response = await fetch(`/api/search?q=${query}`); renderResults(await response.json()); }); Проблема здесь не в fetch() как таковом, а в отсутствии контроля актуальности асинхронной операции: любой завершившийся запрос получает возможность изменить состояние интерфейса. Если устаревшие запросы больше не нужны, для fetch() их можно отменять через AbortController: let controller; search.addEventListener('input', async event => { controller?.abort(); controller = new AbortController(); try { const query = encodeURIComponent(event.target.value); const response = await fetch(`/api/search?q=${query}`, { signal: controller.signal }); if (!response.ok) { throw new Error(`HTTP ${response.status}`); } const results = await response.json(); renderResults(results); } catch (error) { if (error.name !== 'AbortError') { console.error(error); } } }); При следующем вводе abort() переводит предыдущий AbortSignal в состояние aborted. Связанная с ним fetch-операция прерывается, поэтому её устаревший результат не попадёт в renderResults(). AbortSignal нельзя использовать повторно после отмены: он остаётся в состоянии aborted. Для следующей операции необходимо создать новый AbortController: controller.abort(); controller = new AbortController(); Важно понимать границу такой отмены. abort() прерывает клиентскую fetch-операцию и чтение тела ответа, но не гарантирует прекращение обработки запроса на сервере. К моменту отмены запрос уже мог быть отправлен, а сервер мог начать его обработку. AbortController и debounce также решают разные задачи. debounce уменьшает количество запускаемых запросов, откладывая выполнение до паузы во вводе. AbortController позволяет прервать клиентскую операцию, которая уже была запущена, но перестала быть актуальной. В интерактивном поиске эти механизмы можно использовать совместно. При этом отмена — не единственный способ защиты от устаревших результатов. Если операцию нельзя или не требуется отменять, актуальность результата можно проверить непосредственно перед изменением состояния: let requestId = 0; search.addEventListener('input', async event => { const id = ++requestId; const query = encodeURIComponent(event.target.value); const response = await fetch(`/api/search?q=${query}`); if (!response.ok) { throw new Error(`HTTP ${response.status}`); } const results = await response.json(); if (id === requestId) { renderResults(results); } }); Здесь каждый запрос получает монотонно возрастающий идентификатор. Изменить интерфейс может только результат последней запущенной операции. Даже если более старый запрос завершится позже, его результат будет проигнорирован. 🔥Основной принцип шире конкретного API: результат асинхронной операции должен изменять состояние только до тех пор, пока эта операция остаётся актуальной. 📣 Code Ready | #практика
27 · 1.8K ·

Рядом в ленте

CCode Ready | FrontendФотографияCCode Ready | Frontend👨‍💻 Интересная статья-подборка на Хабре: «Зря вы забыли эти HTML- и CSS-фичи»! В этой статье: • Вспомните, как contenteditable позволяет редактировать содержимо
это сообщение
CCode Ready | Frontend😎 Интересная статья лежит на Хабре: «П維чему нейро考ети дел思ют так»! В этой статье: • Объясняется, как токены превращаются в эмбеддинги и как модель представляет CCode Ready | Frontend✍️ Frontend Interview Questions — шпаргалка для подготовки к собеседованиям! В репозитории собраны не просто вопросы, а готовые ответы и пояснения по ключевым к
CCode Ready | FrontendCode Ready | Frontend@code_ready · канал · Технологии
21 660подписчиков1 634средний охват поста
Лента площадки Открыть в Telegram

Открытая публичная лента из поискового индекса ChatCrawler — «Google по публичному Telegram»; обновляется по мере обхода площадки. Время — UTC.

Только публичный контент, официальный API Telegram. О проекте · Вопросы · Чего мы не делаем · Убрать страницу из выдачи · Каталог · Поиск · Как мы считаем