如何创建仅生成http请求一次的角度js服务

时间:2015-11-03 00:16:05

标签: javascript angularjs

我有以下angularjs服务

var assetLookUpTransformService = function($http, $q) {
this.data = null;
var self = this;

this.doStuff = function() {

    var defer = $q.defer();

    if (self.data) {
        defer.resolve(self.data[0].DisplayName);
    } else {
        $http({
            url: '../AssetLookup/GetAssetLookUp',
            method: "GET"
        }).success(function(response) {
            self.data = response;
            defer.resolve(self.data[0].DisplayName);
        });
    }
        return defer.promise;
    }
}

一切正常,因为一旦$ http请求返回所有后续调用" doStuff"从数据返回数据而不是发出新请求。

然后我遇到的问题是我在页面加载后正在进行一堆调用。发生的事情是,对doStuff的第一次调用将发出$ http请求,但是在第一次http请求返回之前发生的对dostuff的任何调用也将发出$ http请求。

有没有办法调用doStuff"等待"对于未完成的$ http请求,在创建之前返回。

或者有没有办法确保$ http请求只发生一次?

2 个答案:

答案 0 :(得分:3)

缓存承诺,而不是数据。数据封装在promise中,并且将始终返回给它的任何请求。

var assetLookUpTransformService = function($http, $q) {
var self = this;

    this.doStuff = function() {
        if (!self.deferred) {
            self.deferred = $q.defer();

            $http({
                url: '../AssetLookup/GetAssetLookUp',
                method: "GET"
            }).success(function(response) {
                self.deferred.resolve(response[0].DisplayName);
            });
        }
        return self.deferred.promise;
    }
}

答案 1 :(得分:0)

为什么不在第一次打电话给doStuff之后再拨打这些电话?

示例:

this.doStuff = function(afterRequests) {
   var defer = $q.defer();

if (self.data) {
    defer.resolve(self.data[0].DisplayName);
} else {
    $http({
        url: '../AssetLookup/GetAssetLookUp',
        method: "GET"
    }).success(function(response) {
        self.data = response;
        defer.resolve(self.data[0].DisplayName);
        //make each request in here.
        afterRequests.forEach(function(request) {
           $http(request).success(function(response) { 
           //use self.data here
           });
        });
    });
}
    return defer.promise;
}

如果由于某种原因你必须同时制作doStuff(例如它已经很长时间运行),那么你可以使用$ rootScope。$ broadcast来定位你可能需要渲染数据的控制器。 / p>