在 AngularJS 服务中只调用一次/缓存来自 $http 的数据 [英] Calling only once / caching the data from a $http get in an AngularJS service

查看:25
本文介绍了在 AngularJS 服务中只调用一次/缓存来自 $http 的数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这听起来可能是一个非常简单/愚蠢的问题,但我需要问它,因为我以前从未遇到过这种情况……好吧,我的 angularJS 应用程序中有一项服务.该服务目前包含 4 种方法,它们都执行 80% 相同的功能/代码,我希望使其更有效率.这是我的服务的样子(删除了很​​多代码):

This may sound like a really simply/stupid question but I need to ask it as I haven't came across this scenario before... okay I have a service in my angularJS app. this service currently contains 4 methods that all perform 80% the same functionality/code and I wish to make this more efficient. Here is what my service looks like (with a lot of code removed):

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

        var townList = {};

        townList.getTownList = function () {

            return $http({method: 'GET', url: '/api/country/cities'})
                .then(function (response) {

                    // HERE WE FORMAT THE response as desired... that creates a returnArray
                    var returnArray = [];
                    // loop through the countries
                    var JsonData = response.data;

                    for (key in JsonData['countries']) {
                         // formatting code...
                    }
                    // end of repeated CODE

                    return returnArray; // this is array, we don't do any formatting here

                });
        };


     townList.getCurrentTown = function (place) {

            return $http({method: 'GET', url: '/api/country/cities'})
                .then(function (response) {

                    // HERE WE FORMAT THE response as desired... that creates a returnArray
                    var returnArray = [];
                    // loop through the countries
                    var JsonData = response.data;

                    for (key in JsonData['countries']) {
                         // formatting code...
                    }
                    // end of repeated code

                    // now the format further / work with the returnArray...
                    for (var i = 0; i < returnArray.length; i++) {
                        // do stuff
                    }
                    return currentTown; // this is a string

                });
        };


        townList.getCurrentCountry = function (place) {

            return $http({method: 'GET', url: '/api/country/cities'})
                .then(function (response) {

                    // HERE WE FORMAT THE response as desired... that creates a returnArray
                    var returnArray = [];
                    // loop through the countries
                    var JsonData = response.data;

                    for (key in JsonData['countries']) {
                         // formatting code...
                    }
                    // end of repeated code

                    // now the format further / work with the returnArray...
                    for (var i = 0; i < returnArray.length; i++) {
                        // do stuff
                    }
                    return currentCountry; // this is a string

                });
        };

        return townList;

    }
)
;

现在,在返回对象数组或字符串之前,我在每个方法中重复相同的 $http 'GET' 和相同的格式化代码(这是很多嵌套循环).这远非有效!将这个功能放到它自己的函数中的最好方法是什么,所以我们只调用一次 GET url 但仍然为每个方法返回一个承诺?我应该将 $http({method: 'GET', url: '/api/country/cities'}) 的结果设置为 var 并在格式化之前将其注入/传递到每个方法中吗?必要时提供数据?我应该使用某种 $cacheFactory 吗?

Now I repeat the same $http 'GET' in each method and the same formatting code (which is a lot of nested loops) before returning a object array or a string. This is far from efficent! What is the best way to put this functionality into it's own function so we only call the GET url once but still return a promise with each method? Should I set the results of the $http({method: 'GET', url: '/api/country/cities'}) as a var and inject / pass it into each method before formatting the data if necessary? Should I use some sort of $cacheFactory?

对不起,如果这是一个愚蠢的问题,如果我没有很好地解释自己,我将重新表述这些问题.

Sorry if this is a dumb question and if I haven't explained myself well I shall rephrase the questions.

提前致谢.

推荐答案

正如你所说;这段代码可以(并且应该)以多种方式重构.一个例子:

It is just as you say; this code can (and should) be refactored in many ways. One example:

让我们将 HTTP 内容分解为一个单独的服务,这也将负责缓存.(另一个想法是为 HTTP/远程调用提供一个服务,另一个——也许是一个通用的装饰器——来处理缓存.让我们现在不讨论这么多细节.)让我们把格式化代码放进去另一种方法:

Let us factor the HTTP stuff into a separate service, that will also take care of caching. (Another idea for this would be to have a service for the HTTP/remote calls and another - maybe a general use decorator - to handle caching. LEt us not go into so much detail for now.) And let us put the formatting code in another method:

远程调用服务:

.service('townHttpService', function($http, $q) {
    var cache;

    function getCities() {
        var d = $q.defer();
        if( cache ) {
            d.resolve(cache);
        }
        else {
            $http({method: 'GET', url: '/api/country/cities'}).then(
                function success(response) {
                    cache = response.data;
                    d.resolve(cache);
                },
                function failure(reason) {
                    d.reject(reason);
                }
            });
        }
        return d.promise;
    }

    function clearCache() {
        cache = null;
    }

    return {
        getCities: getCities,
        clearCache: clearCache
    };
})

格式化程序:

.service('townFormatter', function() {
    return function townFormatter(jsonData) {
        // HERE WE FORMAT THE response as desired... that creates a returnArray
        var returnArray = [], key;
        // loop through the countries
        for (key in jsonData['countries']) {
             // formatting code...
        }
        // end of repeated CODE
        return returnArray; // this is array, we don't do any formatting here
    };
})

您的townDataService,按照以上内容编写:

Your townDataService, written in terms of the above:

.factory('townDataService', function (townHttpService, townFormatter) {

    var townList = {};

    townList.getTownList = function () {
        return townHttpService.getCities().then(townFormatter);
    };

    townList.getCurrentTown = function (place) {
        return townHttpService.getCities().then(townFormatter).then(function(cityList) {
            var currentTown;
            for (var i = 0; i < cityList.length; i++) {
                // do stuff
            }
            return currentTown; // this is a string
        });
    };

    townList.getCurrentCountry = function (place) {
        return townHttpService.getCities().then(townFormatter).then(function(cityList) {
            var currentCountry;
            for (var i = 0; i < cityList.length; i++) {
                // do stuff
            }
            return currentCountry; // this is a string
        });

    return townList;
})

这篇关于在 AngularJS 服务中只调用一次/缓存来自 $http 的数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆