Нужно ли отменять тайм-аут AngularJS $http?

Я пытаюсь улучшить производительность своего приложения на мобильных устройствах с медленными сетями.

Первым шагом было добавление "глобального" таймаута для всех http-запросов, я использовал простой request перехватчик для этого - request(config) { return angular.extend({ timeout: 30000 }, config) }, Это работало нормально - вместо бесконечного ожидания ответа я мог отобразить предупреждение о медленной сети (в responseError interceptor), более того, медленный запрос отменяется, поэтому я могу ожидать, что он освободит некоторую полосу пропускания для других запросов.

Сейчас я пытаюсь реализовать еще одну оптимизацию - отмена ожидающих http-запросов до изменения состояния uiRouter, поскольку нет причин загружать ресурсы для состояния, которое больше не будет отображаться. Например, случай, когда пользователь пытается перейти в состояние A, ожидаемые разрешения A ожидают, скучающий пользователь передумал и пытается перейти в состояние B.

Моя текущая реализация основана на $q а также $timeout услуги и пользовательский сервис для сбора тайм-аутов для всех http-запросов и отмены их в пакете при необходимости. Достаточно слов, вот код:

const REQUEST_TIMEOUT = 3000; // 30 secs

function httpRequestsCancellerService($timeout, $transitions, $q) {
  const cancelers = [];

  function cancelAll() {
    while (cancelers.length > 0) {
      const canceler = cancelers.pop();
      canceler.resolve();
    }
  }

  // Cancel all pending http requests before the next transition
  $transitions.onStart({}, cancelAll);

  return {
    createTimeout() {
      const canceler = $q.defer();

      // TODO it will keep running even whe the request is completed or failed
      $timeout(canceler.resolve, REQUEST_TIMEOUT);
      cancelers.push(canceler);

      return canceler.promise;
    }
  };
}

function timeoutInterceptor(httpRequestsCanceller) {
  return {
    request(config) {
      const timeout = httpRequestsCanceller.createTimeout();
      return angular.extend({ timeout }, config);
    }
  };
}

module.exports = function($httpProvider, $provide) {
  'ngInject';
  $provide.service('httpRequestsCanceller', httpRequestsCancellerService);
  $httpProvider.interceptors.push(timeoutInterceptor);
};

Теперь он отлично работает, но имеет небольшой недостаток - $timeout в request перехватчик будет продолжать работать и, наконец, разрешит canceller даже если запрос завершен или не выполнен.

Вопрос в том, должен ли я заботиться об этих отложенных $timeouts? Нужно ли $timeout.cancel их, чтобы освободить некоторые ресурсы или избежать каких-то странных побочных эффектов?

0 ответов

Другие вопросы по тегам