Delay an angular.js $http service

前端 未结 8 1120
感动是毒
感动是毒 2021-01-31 16:32

I have some angular factories for making ajax calls towards legacy ASP.NET .asmx web services like so:

module.factory(\'productService\', [\"$http\",
function ($         


        
相关标签:
8条回答
  • 2021-01-31 16:35

    Developing more on the answer of @stevuu

    responseInterceptors seems to be depreceted (as of 1.2.20) I have modified the code to work on the interceptors mechanism:

    $httpProvider.interceptors.push(function($q, $timeout) {
        return {
            'response': function(response) {
                var defer = $q.defer();
                $timeout(function() {
                            defer.resolve(response);
                    }, 2300);
                return defer.promise;
            }
        };
    });
    
    0 讨论(0)
  • 2021-01-31 16:38

    You can achieve this using the promise api combined with a $timeout. The $http.post function returns a promise from which you can call .success and .error (these are http specific methods). This promise is resolved when the http request is complete. If you build your own promise then you can tell it to delay 2 seconds and then resolve when the http request is complete:

    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;
            }
        }
    
    });
    

    But note - you will have to use promise.then(successCallback, errorCallback) functionality - that is, you'll lose the ability to access http headers, status & config from your controllers/directives unless you explicitly supply them to the object passed to defer.resolve({})

    Links:

    • Defer/Promise Api
    • Http/Promise Api
    • Resolve egghead video
    0 讨论(0)
  • 2021-01-31 16:40

    The new chrome device emulator has a network throttling function:

    enter image description here

    To get there: In Google Chrome, press F12 to open the Developer Tools. Then, on the top left corner, click the "Toggle device mode" icon (left to the "Elements" menu).

    0 讨论(0)
  • 2021-01-31 16:43

    You could use the $q service for defer().promise pattern:

    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;
        }
    });
    

    But if you are really mock testing, the better solution is to look into ngMock: http://docs.angularjs.org/api/ngMock.$httpBackend

    0 讨论(0)
  • 2021-01-31 16:46

    In response to the testing aspect of your question, Fiddler has a really useful function that helps when you need to simulate delays:

    1. Click on the AutoResponders tab in Fiddler.
    2. Add a rule with a regex that matches the URL of the request you want to delay.
    3. Set the "respond with" to "*delay:1000" where the number is the delay in milliseconds.

    The AutoResponder functionality in Fiddler is extremely useful for testing JS that involves a lot of http requests. You can set it to respond with particular http error codes, block responses, etc.

    0 讨论(0)
  • 2021-01-31 16:47

    If you are using a service that returns a promise, then inside you should put a return before the $timeout as well because that returns just another promise.

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

    Hope it helps someone!

    0 讨论(0)
提交回复
热议问题