简体   繁体   English

AngularJS:防止调用多个$ http请求以获取相同数据

[英]AngularJS: Prevent calling multiple $http request to get same data

I still don't understand how the Promise API works. 我仍然不了解Promise API的工作方式。 I want to know if there's a way to get a data whenever I need it without calling multiple HTTP request. 我想知道是否有一种方法可以随时获取数据而无需调用多个HTTP请求。 Here's an exemple : 这是一个例子:

Session Service : All it does is either get the session object (which contains datas) or get session ID which returns a number. 会话服务 :它所做的就是获取会话对象(包含数据)或获取返回数字的会话ID。

app.factory('sessionFactory', ['$resource', 'requestFactory',
function ($resource, requestFactory) {

    var oSession = {};

    var session = {
        /**
         * Get session ID
         * @return {Number}
         */
        sessionID: function () {
            if (typeof oSession.id !== "undefined") {
                return oSession.id;
            } else {
                return requestFactory.getObject('/application/current_session').then(function (response) {
                    oSession = response;
                    return oSession.id;
                });
            }
        },

        /**
         * Get session object (GET)
         * @return {Object} data in JSON format
         */
        getCurrentSession: function () {
            if (!oSession.id) {
                return requestFactory.getObject('/application/current_session').then(function (response) {
                    oSession = response;
                    return oSession;
                });
            }
        }
    };

    return session;

}]);

Request HTTP Service : This service only does HTTP request. 请求HTTP服务 :此服务仅执行HTTP请求。

app.factory('requestFactory', ['$http', '$q', '$timeout',
function ($http, $q, $timeout) {
    return {
        getObject: function (jsonURL, params) {
            // $q service object
            var deferred = $q.defer();

            // regular ajax request
            $http({
                method: 'GET',
                url: jsonURL,
                params: params
            })
                .success(function (result, status, headers, config) {
                    // promise resolve
                    deferred.resolve(result);
                })
                .error(function (result, status, headers, config) {
                    // called asynchronously if an error occurs
                    // or server returns response with an error status.
                    deferred.reject('Erreur request : ' + status);
                });

            return deferred.promise;
        }
    };
}]);

So to get my Session Object, I do sessionFactory.getCurrentSession with callback function(then...) and it works perfect. 因此,要获取我的会话对象,我使用回调函数(then ...)执行sessionFactory.getCurrentSession,它可以完美地工作。 Later on, I only need to get the session ID so I would do sessionFactory.sessionID, but it works only if I add the callback function (then...), why is that? 稍后,我只需要获取会话ID,就可以使用sessionFactory.sessionID,但是仅当我添加了回调函数(然后...)时它才起作用,为什么呢? I thought my global JavaScript object oSession already has data since the first HTTP request. 我以为自第一个HTTP请求以来,我的全局JavaScript对象oSession已经具有数据。

I want to prevent doing a spaghetti code and keep the code as clean as possible, with a more object approach. 我想通过使用更多的对象方法来防止执行意大利面条式的代码,并保持代码尽可能的干净。 Is it possible? 可能吗?

It looks like you're trying to do too much with the promise API. 似乎您正在尝试对Promise API进行过多处理。 It's already built into the $http service so you shouldn't need to invoke it yourself. 它已经内置在$ http服务中,因此您不需要自己调用它。 Try this instead: 尝试以下方法:

app.factory('requestFactory', ['$http',
function ($http) {
    return {
        getObject: function (jsonURL, params) {
            // regular ajax request
            return $http({
                method: 'GET',
                url: jsonURL,
                params: params
            })
                .success(function (result, status, headers, config) {
                    return result;
                })
                .error(function (result, status, headers, config) {
                    // called asynchronously if an error occurs
                    // or server returns response with an error status.
                    throw new Error('Erreur request : ' + status);
                });
        }
    };
}]);

By returning the result of the $http call, you are in fact returning a promise. 通过返回$ http调用的结果,实际上是在返回一个Promise。 You can then chain additional resolution code onto the return value. 然后,您可以将其他解析代码链接到返回值上。 See the "Chaining Promises" section of the $q documentation . 请参阅$ q文档的“束缚承诺”部分。

IF you want to cache your previous http response so that it will not make an http call again 如果您想缓存以前的http响应,这样就不会再次发出http调用

  1. you can use angular-cached-resource 您可以使用angular-cached-resource

    bower install angular-cached-resource Bower安装angular-cached-resource

    angular.module('myApp',['ngCachedResource']) angular.module('myApp',['ngCachedResource'])

    instead of $resource use $cachedResource , it will cache the network call to local storage, every time you make a call it will resolve immediately even though it makes a call to backend and updated the cache. 而不是$resource使用$cachedResource ,它会将网络调用缓存到本地存储中,每次您进行调用时,即使它调用了后端并更新了缓存,它也会立即解决。

  2. you can also use angular-cache it will cache all your http get calls you can set timeout as well exclude url in its configuration 您还可以使用angular-cache ,它将缓存所有http get调用,您可以设置超时以及在其配置中排除url

bower install angular-cache 凉亭安装角度缓存

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM