限制或延迟AngularJS服务的http请求

时间:2014-06-17 09:45:44

标签: javascript angularjs

我已经创建了一个为我的AngularJS应用程序提供数据的服务,它相当简单,服务只包含许多进行$http调用的方法。问题是,每当我的视图中的HTML项目(产品细节的div)在视口中可见时(我是延迟加载),就会进行此调用,因此用户可以直接滚动到底部页面等,并创建一些请求(通常约50 - 60),将阻止/减慢其他请求或整个应用程序。因此,我需要一种方法来限制,限制,排队或延迟请求 - 排队是最好的,但目前我只是要限制/管理服务中的请求数量。

这就是我在控制器/指令中调用我的服务的方式:

productAvailabilityService.getAvailability(scope.productId).then(function (result) {
    // do stuff with the result... 
});

这是服务

.factory('productAvailabilityService', function ($http) {

        var prodAv = {};  
        prodAv.getAvailability = function (productId) {           
                return $http({
                    method: 'GET',
                    url: '/api/product/getAvailability',
                    params: {
                        'productId': productId
                    }

                }).then(
                    function (response) {
                        return response;
                    }, function () {
                        return 0;
                    });
            }
        };

        return prodAv;
    });

现在我想添加限制功能......就像这样:

.factory('productAvailabilityService', function ($http) {

    var prodAv = {};
    prodAv.requests = 0;

    prodAv.getAvailability = function (productId) {

        if (prodAv.requests > 6) {
            return function () {
                return 'Too many requests';
            };
        } else {

            prodAv.requests++;
            return $http({
                method: 'GET',
                url: '/api/product/:productId/getAvailability',
                params: {
                    'productId': productId
                }

            }).then(
                function (response) {
                    prodAv.requests--;
                    return response;
                }, function () {
                    prodAv.requests--;
                    return 0;
                });
        }
    };

    return prodAv;
});

当请求数量大于6时,这会给我一个错误,我似乎无法修复.getAvailability(...).then is not a function,任何人都可以看到我做错了...也是这个方法做的看起来有点不对,有没有更好的方法来管理我可以调用服务/运行$http请求的次数?提前谢谢!

3 个答案:

答案 0 :(得分:1)

您必须使用productAvailabilityService的承诺。你返回一个函数而不是一个promise,所以" then()"在第一行代码中抛出错误..

这是带有promise的代码部分:

.factory('productAvailabilityService', function ($http,$q) {

var prodAv = {};
prodAv.requests = 0;

prodAv.getAvailability = function (productId) {

    if (prodAv.requests > 6) {
        var deferred = $q.defer();
        deferred.reject("no more than 6 calls");
        return deferred.promise;
    }else{ //etc.

如果您管理延迟通话,也可以使用解析功能

答案 1 :(得分:1)

添加此DelayHttp

app.factory('DelayHttp', ($http, $timeout) => {
    let counter = 0,
        delay = 100;

    return (conf) => {
        counter += 1;

        return $timeout(() => {
            counter -= 1;
            return $http(conf);
        }, counter * delay);
    };
});

用法:

return DelayHttp({
    url: url,
    method: 'GET',
    params: params
});

以100ms间隔或最多10个请求/秒的速度排队并执行请求。您可以调整延迟以匹配所需的吞吐量。

答案 2 :(得分:0)

我会设置一个时间间隔并等到用户到达其所需内容之后再发出类似

的请求
 var timer;
 function getData(){
          $timeout.cancel(timer);
          timer=$timeout(function(){
                $http.get(url)
          },200);
 }