Как прервать незавершенный запрос

Java внешний интерфейс JavaScript Chrome

Вам часто приходится делать частые запросы в веб-приложении во время взаимодействия с пользователем или последнего ввода. Например, операция автоматического завершения при вводе текста или операция увеличения и уменьшения масштаба карты. Давайте задумаемся над этими примерами. Первый — автозаполнение, каждый раз, когда мы печатаем (или реже используемdebounce) мы оформим запрос. Если пользовательский ввод изменится, старый запрос не будет иметь отношения к настоящему, пока мы продолжаем вводить ввод (например, «java» и «javascript»). Может быть, есть много избыточных запросов, когда мы получаем то, что нам нужно.

Тогда есть пример карты. Когда мы масштабируем для просмотра карты, нас больше не интересуют плитки с предыдущим уровнем масштабирования. В то же время многие запросы все еще ожидают избыточных данных.

В нашем первом примере давайте посмотрим на собственный код, который реализует сценарий автозаполнения. Для целей этой статьи мы будем использовать более современную выборку вместо XMLHttpRequest для выполнения сетевых запросов. код показывает, как показано ниже:

autocompleteInput.addEventListener('keydown', function() {

    const url = "https://api.example.com/autocomplete"

    fetch(url)
        .then((response) => {
            // Do something with the response
            updateAutocompleteMenu()
        })
        .catch((error) => {
            // Something went wrong
            handleAutocompleteError(error);
        })

});

Проблема с этим примером заключается в том, что каждый запрос должен быть выполнен, даже если он больше не актуален. Мы могли бы реализовать дополнительную логику в updateAutocompeleteMenu, чтобы предотвратить дополнительный код, но на самом деле это не остановило бы запрос. Стоит отметить, что браузерыЛимит одновременных запросовЭто означает, что после срабатывания пределов запрос будет очередным (и каждый браузер ограничен).

Abortable Fetch

Новые технологии браузера, которые мы можем использовать для решения вышеуказанных проблем,Abortable Fetch. Abortable Fetch зависит от спецификаций браузераAbortController. Этот контроллер имеет свойство signal, которое мы используем для передачи, и используем метод прерывания контроллера для отмены запроса в более позднее время.

Пример выглядит следующим образом:

autocompleteInput.addEventListener('keydown', function() {
const url = "https://api.example.com/autocomplete"
let controller;
let signal;

autocompleteInput.addEventListener('keyup', () => {

    if (controller !== undefined) {
        // Cancel the previous request
        controller.abort();
    }

    // Feature detect
    if ("AbortController" in window) {
        controller = new AbortController;
        signal = controller.signal;
    }

    // Pass the signal to the fetch request
    fetch(url, {signal})
        .then((response) => {
            // Do something with the response
            updateAutocompleteMenu()
        })
        .catch((error) => {
            // Something went wrong
            handleAutocompleteError(error);
        })
    });

});

Мы делаем обнаружение функций, чтобы увидеть, можем ли мы использовать AbortController (он поддерживается в Edge, Firefox, Opera и Chrome 66!). Мы проверяем, был ли создан контроллер, и если да, то вызываем controller.abort() для отмены предыдущего запроса. Вы также можете отменить несколько выборок одновременно с одним и тем же сигналом.

небольшой пример

Я создал небольшой пример, показывающий, как использовать Abortable Fetch, основываясь на идее сценариев автозаполнения (без каких-либо подробностей реализации!). чтобы понять, что происходит всякий раз, когда вводится сетевой запрос. Если вы сделаете новый ввод до завершения старого запроса, он прервет предыдущую выборку. На практике это выглядит примерно так:

abortable fetch

исходный код

думать глубоко

Возможно, самая крутая часть AbortController заключается в том, что он был разработан как общий механизм прерывания асинхронных задач. этоWHATWG specificationчасть. Это означает, что это спецификация DOM, а не спецификация языка (ECMAScript), но она по-прежнему полезна для фронтенд-разработки. Вы можете использовать его как более четкий асинхронный механизм потока управления при реализации асинхронных задач (т. е. при использовании промисов). этоСупер статья Брэма Ван Дамма для более подробного примера статьиТам будет больше подробностей о том, что я сказал.

Этот перевод сОригинал — Отмена запросов с прерыванием выборки. Нерегулярно обновляетсятехнический пост в блогеДобро пожаловатьstar. Из-за моего ограниченного уровня ошибки неизбежны, пожалуйста, поправьте меня! Пожалуйста, указывайте источник при перепечатке, сохраняйте оригинальную ссылку и информацию об авторе.