Перехватчики Axios зависают при отправке запроса

avatar
Григорий Архипов
8 августа 2021 в 17:26
82
0
1

Я пытаюсь предотвратить ограничение скорости с помощью Axios Interceptors

Для этого я создал класс RequestManager. У него есть метод отправки запроса, после отправки запроса он анализирует заголовки и создает новый объект в this.routes. this.routes хранит информацию RateLimits для каждого маршрута. Перед отправкой запроса перехватчик проверяет ограничения скорости для текущего маршрута и, если это последний запрос, ждет сброса ограничений скорости с использованием задержки и продолжает отправлять запросы

.

Ну, все происходит не так, как я хочу. Например, я отправляю 5 запросов на один маршрут, по этому маршруту 5 запросов режут за 20 секунд, но мой код не ждет 20 секунд для сброса ограничения скорости и отправляет запрос. Он даже не удосуживается установить данные ограничения скорости в this.routes, почему?

export const delay = promisify(setTimeout);
    public async interceptRequest(config: AxiosRequestConfig) : Promise<AxiosRequestConfig> {
      console.log("Check the `this.routes` to prevent rate limits")
      if(this.routes.size <= 0) return config;
      const hash = this.hash(this.getMajorId(config.url as Route), config.method as RestMethods);
      const route = this.routes.get(hash);
      console.log(route, hash, this.routes)
      // Prevent global rate limit
      if (this.globalCounter >= 50) {
        return new Promise<AxiosRequestConfig>((resolve) => setTimeout(() => resolve(config), 1000));
      }
      if (route.remaining <= 0) {
        // Calculate time to reset
        const reset = route.remaining - Date.now();
        return new Promise<AxiosRequestConfig>((resolve) => setTimeout(() => resolve(config), reset));
      }
      return config;
    }
    public async request<R, B = null>(
      route: Route,
      method: RestMethods = RestMethods.Get,
      body: Nullable<B> = null
    ): Promise<AxiosResponse<R>> {
      // @ts-ignore
      const response: AxiosResponse<R> = await this.axios(route, {
        method,
        data: body
      }).catch(() => {});
      const hash = this.hash(route, method);
      this.routes.set(hash, {
        limit: parseInt(response.headers["X-RateLimit-Limit"]),
        reset: parseInt(response.headers["X-RateLimit-Reset"]),
        remaining: parseInt(response.headers["X-RateLimit-Remaining"])
      });
      console.log("Set information about rate limits in `this.routes`");
      this.globalCounter++;
      return response;
    }

Вывод:

Check the `this.routes` to prevent rate limits
Check the `this.routes` to prevent rate limits
Check the `this.routes` to prevent rate limits
Check the `this.routes` to prevent rate limits
Check the `this.routes` to prevent rate limits
Check the `this.routes` to prevent rate limits
Check the `this.routes` to prevent rate limits
Check the `this.routes` to prevent rate limits
Check the `this.routes` to prevent rate limits
Check the `this.routes` to prevent rate limits
Set information about rate limits in `this.routes`

По логике, он должен был напечатать это:

Check the `this.routes` to prevent rate limits
Set information about rate limits in `this.routes`
Check the `this.routes` to prevent rate limits
Set information about rate limits in `this.routes`
...
Источник

Ответы (0)