API fetch — это API JavaScript для выполнения HTTP-запросов. Это замена XMLHttpRequest, которая устарела в большинстве браузеров. Это API на основе обещаний, что означает, что он возвращает объект Promise, который разрешается или отклоняется после завершения запроса.
Давайте посмотрим на функцию fetch().
fetch(url)
.then((response) => response.json())
.then((data) => console.log(data))
.catch((error) => console.error(error));
Это здорово, но иногда мы хотим отменить уже инициированный запрос.
Давайте рассмотрим следующий пример.
Предположим, у нас есть поисковый ввод, и мы хотим показать предложения по типам пользователей. когда пользователь вводит символ, мы вызываем функцию fetch() и передаем значение поля ввода поиска в качестве параметра URL.
fetch(`${url}?q=${searchInput.value}`)
.then((response) => response.json())
.then((data) => console.log(data))
.catch((error) => console.error(error));
Проблема:
Функция fetch() вызывается каждый раз, когда пользователь вводит символ. Это неэффективный подход, поскольку он вызывается несколько раз, и нас интересует только последний ответ.
Решение:
Используйте функцию debounce(), чтобы ограничить количество вызовов функции fetch(). Он будет вызываться только после того, как пользователь перестанет печатать в течение определенного периода времени (100 мс). Это хорошая практика, позволяющая избежать ненужных вызовов API.
Пограничный случай: что, если пользователь начнет печатать сразу после вызова debounce(). В этом случае функция fetch() будет вызвана снова. Это лучше, чем предыдущий подход.
Как с этим справиться?
Вот здесь и пригодится AbortController. Мы можем использовать AbortController для отмены уже инициированного запроса (используя выборку). Современные браузеры имеют встроенный интерфейс AbortController.
Вы можете создать новый объект AbortController, используя конструктор AbortController().
Характеристики:
Возвращает экземпляр объекта AbortSignal, который можно использовать для связи или прерывания запроса DOM.
Метод:
Прерывает запрос DOM до его завершения. Когда мы прерываем асинхронную операцию, обещание отклоняется с DOMException с именем AbortError.
Реальный пример
Я не буду создавать здесь функцию debounce(), но давайте рассмотрим следующий пример.
<!DOCTYPE html> <html> <body> <input id="search" type="number" /> <script> const results = []; const search = document.getElementById("search"); let controller = new AbortController(); let signal = controller.signal;
const getPost = async (value, signal) => { try { const response = await fetch( `https://jsonplaceholder.typicode.com/posts/${value}`, { signal } ); results.push(`Success: ${value}`); } catch (error) { if (error.name === "AbortError") { results.push("API failure"); } else { console.log("Some other error"); } } finally { console.log("Status", results); } }; const onChange = () => { const value = search.value; if (value) { controller.abort(); controller = new AbortController(); signal = controller.signal; getPost(value, signal); } }; search.onkeyup = onChange; </script> </body> </html>
Реагировать пример
useEffect(() => { const controller = new AbortController(); const signal = controller.signal; const results = []; const getPost = async (value) => { try { const response = await fetch( `https://jsonplaceholder.typicode.com/posts/${value}`, { signal } ); results.push(`Success: ${value}`); } catch (error) { if (error.name === "AbortError") { results.push("API failure"); } } finally { console.log("Status", results); } };
getPost(1);
return () => { // Cancel the request on unmount controller.abort(); }; }, []);
Примечание. Лучшим подходом может быть сочетание debounce() и AbortController.
Обязательно прочитайте, если вы еще не читали
Реагирование на передовые методы и шаблоны для сокращения кода — Часть 1
Реагирование на передовые практики и шаблоны для сокращения кода — Часть 2
28 методов массива Javascript: памятка для разработчика
Больше контента на Средних
Следуйте за мной на Github, Twitter, LinkedIn, Dev.to и Stackblitz.