Как работают угловые перехватчики?

javascript angularjs

220 просмотра

1 ответ

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

var app = angular.module("myApp", []);

app.factory("timestampMaker", [
  function() {
    var timestampMaker = {
      request: function(config) {
        console.log(config);
        config.requestTimestamp = new Date().getTime();
        return config;
      },
      response: function(response) {

        response.config.responseTimestamp = new Date().getTime();
        return response;
      }
    };
    return timestampMaker;
  }
]);

app.config(['$httpProvider',
  function($httpProvider) {
    $httpProvider.interceptors.push('timestampMaker');
  }
]);

app.run(function($http) {
  $http.get('https://api.github.com/users/naorye/repos').then(function(response) {
    console.log(response);
    var time = response.config.responseTimestamp - response.config.requestTimestamp;
    console.log("The request took" + (time / 1000) + "seconds")
  });
});
<html ng-app="myApp">

<head>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
</head>

</html>

Когда я делаю console.log(config)внутри функцию запроса, здесь вывод на консоли. введите описание изображения здесь

Я не получаю, как responseTimestampпоявляются в объекте конфигурации запроса, где, как это определено внутри функции ответа

Автор: Deepak Kumar Padhy Источник Размещён: 08.11.2019 11:23

Ответы (1)


0 плюса

Обратите внимание, что я использовал исходный код 1.2.x, который добавлен в вопрос.

$httpProviderэто поставщик, который предоставляет вам $httpуслуги.

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

Это то, что вы делаете здесь

app.config(['$httpProvider',
  function($httpProvider) {
    $httpProvider.interceptors.push('timestampMaker');
  }
]);

и это может быть сделано только во время конфигурации, потому что для каждого поставщика документов могут быть настроены до запуска приложения

Вы можете увидеть выставленный массив в исходном коде в строке 159

var responseInterceptorFactories = this.responseInterceptors = [];

Когда вы запрашиваете $httpсервис, внедряя его в ваш сервис / контроллер, $getвыполняется функция. В этой функции ваш массив перехватчиков повторяется, как вы можете видеть в исходном коде в строке 179

   var reversedInterceptors = [];
   forEach(responseInterceptorFactories, function(interceptorFactory, index) {
      var responseFn = isString(interceptorFactory) ? $injector.get(interceptorFactory) : $injector.invoke(interceptorFactory);

      /**
       * Response interceptors go before "around" interceptors (no real reason, just
       * had to pick one.) But they are already reversed, so we can't use unshift, hence
       * the splice.
       */
      reversedInterceptors.splice(index, 0, {
        response: function(response) {
          return responseFn($q.when(response));
        },
        responseError: function(response) {
          return responseFn($q.reject(response));
        }
      });
    });

По соглашению они меняют порядок. Вы можете видеть, что, используя строку, они получают ссылку на функцию, используя $injector.getили $injector.invoke, и, используя ее, $q.when()мы можем представить их в цепочку обещаний, даже если они представляют собой синхронный код - см. Это Можно ли использовать $ q.all в AngularJS с функцией что не возвращает .promise? если вы не уверены, что я имел в виду$q.when()

Пока что у нас есть массив с функциями, которые похожи на обещания (спасибо $q.when()). Когда вы запрашиваете данные через, $httpкак это

$http.get('https://api.github.com/users/naorye/repos').then(function(response) {
    console.log(response);
    var time = response.config.responseTimestamp - response.config.requestTimestamp;
    console.log("The request took" + (time / 1000) + "seconds")
  });

даже если у вас есть .get(), это просто ярлык для всех тех же функций, которые здесь

В коде соответствующая часть это:

Сначала создается цепной массив с двумя значениями: внутренней функцией, которая не важна для нашей цели (но она возвращает обещание - это важно), и неопределенным значением.

Наш массив с перехватчиками повторяется, и перехватчики запроса добавляются в начале (перед запросом), а ответ - в конце. Нравится

   function serverRequest {
      // some code
    };
     var chain = [serverRequest, undefined];
    var promise = $q.when(config);

    // apply interceptors
    forEach(reversedInterceptors, function(interceptor) {
      if (interceptor.request || interceptor.requestError) {
        chain.unshift(interceptor.request, interceptor.requestError);
      }
      if (interceptor.response || interceptor.responseError) {
        chain.push(interceptor.response, interceptor.responseError);
      }
    });

затем, завершив цепочку (помните, что наш массив перехватчиков был полон обещаний), код выполняет итерацию, добавляя их все, используя .then(), вызывая их выполнение в цепочке, следуя цепочке обещаний (вы можете в Google)

    while(chain.length) {
      var thenFn = chain.shift();
      var rejectFn = chain.shift();

      promise = promise.then(thenFn, rejectFn);
    }

Наконец, обратный вызов, который вы добавляете successи errorдобавляется в самом конце цепочки, и обещание возвращается

 promise.success = function(fn) {
  promise.then(function(response) {
    fn(response.data, response.status, response.headers, config);
  });
  return promise;
};

promise.error = function(fn) {
  promise.then(null, function(response) {
    fn(response.data, response.status, response.headers, config);
  });
  return promise;
};

return promise;

Единственная часть, в которой я не уверен - это использование undefinedв массиве цепочек

Резюме

Вы добавляете имя для своих сервисов, $HttpProviderиспользуете $invokeсервис для их получения и добавляете их в цепочку обещаний, используя $q.when(), возвращая обещание. В конце этого ваши обратные вызовы для определенного $httpзапроса добавляются.

Автор: Gonzalo.- Размещён: 15.03.2017 08:09
Вопросы из категории :
32x32