Как Axios реализует повтор запроса?

внешний интерфейс JavaScript
Как Axios реализует повтор запроса?

существуетКак Axios отменяет повторяющиеся запросы?В этой статье брат Абао представилAxiosкак отменить повторяющиеся запросы иCancelTokenПринцип работы. И эта статья расскажет, как пройтиПерехватчик или адаптерДля реализации функции запроса повторения. Так зачем запрос повторить? Это связано с тем, что в некоторых случаях, например, когда время запроса, мы хотим автоматически повторно инициировать запрос, чтобы повторить попытку выполнения соответствующей операции.

Следующий A Baoge расскажет, как использоватьAxiosПредусмотрены перехватчики или адаптеры для реализации функции повтора запроса, если вы не знакомы с перехватчиками и адаптерами Axios, рекомендуется сначала прочитатьКакие уроки можно извлечь из проекта 77.9K Axios?Эта статья. Далее давайте сначала представим, как использовать перехватчик для реализации схемы повтора запроса.

1. Перехватчик реализует схему повтора запроса

Axiosявляется HTTP-клиентом на основе Promise, а протокол HTTP основан на запросах и ответах:

Таким образом, Axios обеспечиваетПерехватчики запросов и перехватчики ответовЧтобы обрабатывать запрос и ответ отдельно, их роль выглядит следующим образом:

  • Перехватчик запроса. Роль перехватчика этого типа заключается в унифицированном выполнении определенных операций перед отправкой запроса, таких как добавление поля токена в заголовок запроса.
  • Перехватчик ответа: функция перехватчика этого типа заключается в единообразном выполнении определенных операций после получения ответа сервера, например, автоматический переход на страницу входа в систему, когда обнаруживается, что код состояния ответа равен 401.

Настроить перехватчик в Axios очень просто:axios.interceptors.requestа такжеaxios.interceptors.responseпредоставленный объектuseметод, вы можете установить перехватчик запроса и перехватчик ответа отдельно:

export interface AxiosInstance {
  interceptors: {
    request: AxiosInterceptorManager<AxiosRequestConfig>;
    response: AxiosInterceptorManager<AxiosResponse>;
  };
}

export interface AxiosInterceptorManager<V> {
  use(onFulfilled?: (value: V) => V | Promise<V>, 
    onRejected?: (error: any) => any): number;
  eject(id: number): void;
}

Для функции запроса повторных попыток мы хотим позволить пользователю устанавливать не только количество повторных попыток, но и время задержки повторной попытки. В случае сбоя запроса, если объект конфигурации запроса настроен с количеством повторных попыток, Axios повторно инициирует запрос, чтобы повторить операцию. Чтобы иметь возможность повторить запрос глобально, мы реализуем функцию повтора запроса на перехватчике ответа, Конкретный код выглядит следующим образом:

axios.interceptors.response.use(null, (err) => {
  let config = err.config;
  if (!config || !config.retryTimes) return Promise.reject(err);
  const { __retryCount = 0, retryDelay = 300, retryTimes } = config;
  // 在请求对象上设置重试次数
  config.__retryCount = __retryCount;
  // 判断是否超过了重试次数
  if (__retryCount >= retryTimes) {
    return Promise.reject(err);
  }
  // 增加重试次数
  config.__retryCount++;
  // 延时处理
  const delay = new Promise((resolve) => {
    setTimeout(() => {
      resolve();
    }, retryDelay);
  });
  // 重新发起请求
  return delay.then(function () {
    return axios(config);
  });
});

Приведенный выше код не сложен, и соответствующий поток обработки показан на следующем рисунке:

Познакомившись с тем, как использовать перехватчик для реализации функции повторной попытки запроса, давайте представим схему адаптера для реализации повторной попытки запроса.

Следуйте «Дорога к бессмертному совершенствованию с полным стеком», чтобы прочитать 4 бесплатные электронные книги (всего более 30 000 загрузок) и 50 серий руководств по TS, изначально написанных А Баогэ.

2. В адаптере реализована схема запроса повтора

Axios представляет адаптеры, которые позволяют ему поддерживать среду как браузера, так и среды Node.js. Для среды браузера он инкапсулируетXMLHttpRequestAPI для отправки HTTP-запросов, а для среды Node.js — встроенный в Node.js.httpа такжеhttpsмодуль для отправки HTTP-запросов.

существуетКак кэш Axios запрашивает данные?В этой статье Brother Abao рассказывает, как реализовать функцию кэширования данных запроса, улучшив адаптер Axios по умолчанию. Точно так же мы можем реализовать функцию повторной попытки запроса, расширив адаптер Axios по умолчанию.

Прежде чем рассказать, как улучшить адаптер по умолчанию, давайте взглянем на встроенный Axios.xhrAdapterадаптер, который определен вlib/adapters/xhr.jsВ файле:

// lib/adapters/xhr.js
module.exports = function xhrAdapter(config) {
  return new Promise(function dispatchXhrRequest(resolve, reject) {
    var requestData = config.data;
    var requestHeaders = config.headers;

    var request = new XMLHttpRequest();
    // 省略大部分代码
    var fullPath = buildFullPath(config.baseURL, config.url);
    request.open(config.method.toUpperCase(), buildURL(fullPath, config.params, config.paramsSerializer), true);
    // Set the request timeout in MS
    request.timeout = config.timeout;

    // Listen for ready state
    request.onreadystatechange = function handleLoad() { ... }

    // Send the request
    request.send(requestData);
  });
};

Это понятноxhrAdapterАдаптер — это функциональный объект, который получаетconfigпараметр и вернутьPromiseобъект. пока вxhrAdapterвнутри адаптера, который со временем будет использоватьXMLHttpRequestAPI для отправки HTTP-запросов. Чтобы реализовать функцию запроса повторной попытки, мы можем рассмотреть возможность ее улучшения с помощью функций более высокого порядка.xhrAdapterфункция адаптера.

2.1 Определение функции retryAdapterEnhancer

Чтобы дать пользователям больше гибкости в управлении функцией повторной попытки запроса, мы определяемretryAdapterEnhancerфункция, которая принимает два аргумента:

  • адаптер: предварительно расширенный объект адаптера Axios;
  • options: объект конфигурации кэша, этот объект поддерживает 2 свойства, которые используются для настройки различных функций:
    • раз: глобально задайте количество повторных попыток запроса;
    • задержка: глобальная установка времени задержки запроса в мс.

пониматьretryAdapterEnhancerПосле параметров функции давайте посмотрим на конкретную реализацию функции:

function retryAdapterEnhancer(adapter, options) {
  const { times = 0, delay = 300 } = options;

  return async (config) => {
    const { retryTimes = times, retryDelay = delay } = config;
    let __retryCount = 0;
    const request = async () => {
      try {
        return await adapter(config);
      } catch (err) {
        // 判断是否进行重试
        if (!retryTimes || __retryCount >= retryTimes) {
          return Promise.reject(err);
        }
        __retryCount++; // 增加重试次数
        // 延时处理
        const delay = new Promise((resolve) => {
          setTimeout(() => {
            resolve();
          }, retryDelay);
         });
         // 重新发起请求
         return delay.then(() => {
           return request();
         });
        }
      };
   return request();
  };
}

Приведенный выше код не сложен, а основная логика обработки показана на следующем рисунке:

2.2 Использование функции retryAdapterEnhancer

2.2.1 Создайте объект Axios и настройте параметры адаптера
const http = axios.create({
  baseURL: "http://localhost:3000/",
  adapter: retryAdapterEnhancer(axios.defaults.adapter, {
    retryDelay: 1000,
  }),
});
2.2.2 Отправка запросов с помощью объекта http
// 请求失败不重试
function requestWithoutRetry() {
  http.get("/users");
}

// 请求失败重试
function requestWithRetry() {
  http.get("/users", { retryTimes: 2 });
}

Ну как пройти улучшениеxhrAdapterДобавлен адаптер для реализации функции повтора запроса Axios. Так как полный пример кода содержит много контента, Brother Abao не будет помещать конкретный код. Заинтересованные партнеры могут посетить следующий адрес, чтобы просмотреть образец кода.

Полный пример кода:gist.GitHub.com/Semelinker/9…

Здесь мы рассмотрим текущие результаты примера повторной попытки реализации запроса на реализацию Axios:

3. Резюме

В этой статье описывается, как реализовать повтор запроса в Axios на основеretryAdapterEnhancerфункцию или перехватчик ответа, вы можете легко расширить функциональность повторной попытки запроса. Axios — отличный проект с открытым исходным кодом, и мы можем многому научиться. Если вас интересует разработка и реализация внутренних перехватчиков HTTP Axios, разработка и реализация адаптеров HTTP, а также способы защиты от CSRF-атак, вы можете прочитатьКакие уроки можно извлечь из проекта 77.9K Axios?Эта статья.

Следуйте «Дорога полного стека», чтобы прочитать 4 бесплатные электронные книги (всего более 30 000 загрузок) и 11 руководств по Vue 3 для продвинутых пользователей.Друзья, которые хотят вместе изучать TS/Vue 3.0, могут добавить Abaoge WeChat —— semlinker.

4. Справочные ресурсы