web-dev-qa-db-fra.com

Retarder un service angular.js $ http

J'ai quelques usines angulaires pour faire des appels ajax vers des services Web ASP.NET .asmx hérités comme ceci:

module.factory('productService', ["$http",
function ($http) {
    return {
        getSpecialProducts: function (data) {
            return $http.post('/ajax/Products.asmx/GetSpecialProducs', data);
        }
    }
} ]);

Je teste sur un réseau local, donc les temps de réponse sont "trop" bons. Existe-t-il un moyen judicieux de retarder quelques secondes le $ http de l'appel pour simuler une mauvaise connexion?

Ou dois-je emballer tous les appels aux méthodes d'usine dans un délai d'attente de $?

$timeout(function() {
  productService.getSpecialProducs(data).success(success).error(error);
}, $scope.MOCK_ajaxDelay);
34
Cotten

Question interessante!

Comme vous l'avez dit vous-même, $timeout est le choix le plus logique pour un appel différé. Au lieu d'avoir des appels $timeout partout, vous pouvez utiliser un intercepteur de réponse qui enveloppe la promesse $http dans une promesse $timeout, comme indiqué de manière conceptuelle dans la documentation de $http , et enregistrez-la dans l'un de vos blocs de configuration. Cela signifie que tous les appels $http sont affectés par le délai $timeout. Quelque chose dans le genre de:

$httpProvider.interceptors.Push(function($timeout) {
    return {
        "response": function (response) {
            return $timeout(function() {
                return response;
            }, 2500);
        }
    };
});

En prime, pour "simuler une mauvaise connexion?", Vous pouvez également refuser ou ne rien faire au hasard. Heh heh heh.

53
Steve Klösters

Le nouvel émulateur de périphérique Chrome possède une fonction de limitation de réseau:

enter image description here

Pour vous y rendre: Dans Google Chrome, appuyez sur F12 pour ouvrir les outils de développement. Puis, dans le coin supérieur gauche, cliquez sur l’icône "Basculer en mode appareil" (à gauche du menu "Eléments").

16
Vinz243

Développer plus sur la réponse de @stevuu

responseInterceptors semble être obsolète (à partir de 1.2.20) J'ai modifié le code pour fonctionner sur le mécanisme interceptors:

$httpProvider.interceptors.Push(function($q, $timeout) {
    return {
        'response': function(response) {
            var defer = $q.defer();
            $timeout(function() {
                        defer.resolve(response);
                }, 2300);
            return defer.promise;
        }
    };
});
4
Vladius

Vous pouvez utiliser le service $ q pour le modèle defer (). Promise:

function someFunction(MOCK_ajaxDelay) {
   var deferred = $q.defer();
   $http.post('/ajax/Products.asmx/GetSpecialProducs', data).success(function(response) {
      $timeout(function() {deferred.resolve({ success: true, response: response })}, MOCK_ajaxDelay);  
   }).error(function() {
      $timeout(function() {deferred.resolve({ success: true, response: response } }, MOCK_ajaxDelay);  
   });
   return deferred.promise;
}

someService.someFunction(500).then(function(data) {
    if (data.success) {
      $scope.items = data.response.d;
    }
});

Mais si vous êtes vraiment des simulacres de tests, la meilleure solution consiste à examiner ngMock: http://docs.angularjs.org/api/ngMock . $ HttpBackend

3
Noogen

Tandis que @ stevuu answer est correct, la syntaxe a été modifiée dans les nouvelles versions d'AngularJS depuis lors. La syntaxe mise à jour est la suivante:

$httpProvider.interceptors.Push(["$q", "$timeout", function ($q, $timeout) {
  function slower(response) {
    var deferred = $q.defer();
    $timeout(function() {
        deferred.resolve(response);
    }, 2000);
    return deferred.promise;
  }
  return {
    'response': slower
  };
}]);
2
Pratyush

Vous pouvez y parvenir en utilisant l'API de promesse associée à un délai d'attente de $. La fonction $ http.post renvoie une promesse à partir de laquelle vous pouvez appeler .success et .error (ce sont des méthodes spécifiques à http). Cette promesse est résolu lorsque la demande http est terminée. Si vous créez votre propre promesse, vous pouvez lui imposer un délai de 2 secondes, puis résoudre le problème une fois la requête http terminée:

module.factory('productService', function ($http, $q, $timeout) {

    return {
        getSpecialProducts: function (data) {
            var defer = $q.defer();
            $http.post('/ajax/Products.asmx/GetSpecialProducs', data).success(
              function(data) {
                // successful http request, resolve after two seconds
                $timeout(function() {
                    defer.resolve(data);
                }, 2000)
            }).error(function() {
                defer.reject("Http Error");
            })
            return defer.promise;
        }
    }

});

Mais notez que vous devrez utiliser la fonctionnalité promise.then(successCallback, errorCallback), autrement dit, vous ne pourrez plus accéder aux en-têtes http, aux status & config à partir de vos contrôleurs/directives, à moins que vous ne les fournissiez explicitement à l'objet transmis à defer.resolve({}).

Liens:

0
Ian Haggerty

Si vous utilisez un service qui retourne une promesse, vous devriez alors mettre un return avant le $ timeout , car cela ne renvoie qu'une autre promesse.

return dataService.loadSavedItem({
    save_id: item.save_id,
    context: item.context
}).then(function (data) {
    // timeout returns a promise
    return $timeout(function () {
        return data;
    },2000);
});

J'espère que ça aide quelqu'un!

0
Ferenc Takacs

En réponse à l'aspect test de votre question, Fiddler a une fonction très utile qui vous aide lorsque vous devez simuler des retards:

  1. Cliquez sur l'onglet Répondeurs automatiques dans Fiddler.
  2. Ajoutez une règle avec une expression rationnelle qui correspond à l'URL de la demande que vous souhaitez retarder.
  3. Définissez "répondre avec" sur "* délai: 1000" où le nombre correspond au délai exprimé en millisecondes.

La fonctionnalité de répondeur automatique de Fiddler est extrêmement utile pour tester JS qui implique de nombreuses requêtes http. Vous pouvez le configurer pour répondre avec des codes d'erreur http particuliers, des réponses de bloc, etc.

0
Co7e