AngularJS多次处理调用promise但有一些例外

时间:2016-07-11 14:01:08

标签: javascript angularjs ajax

我之前(AngularJS handle calling promise multiple times)问了这个问题,现在我遇到了不同的障碍。现在我必须得到城市名单,但有一个例外。

城市可以像国家一样被多次调用(在我的旧问题中),我必须缓存数据以防止多次调用相同的数据(城市)。旧问题的解决方案可以阻止多个电话,但现在我必须拨打一些电话(对于新国家/地区的城市)。

所以我的问题是: 如何缓存城市数据以防止调用相同的数据? (如果呼叫是针对新国家/地区的城市列表,我的功能必须抓住。如果是:呼叫服务并获取城市,如果不是:从缓存返回城市)

这是我的服务:

var cityCache = {};
vm.getCities = function (countryCode) {

    if (countryCode!=undefined && !cityCache[countryCode]) {

        vm.cityPromise = $http({
            method: 'POST',
            cache: true,
            url: API + '/api/Global/CountryCities',
            data: {
                "CountryCode": countryCode
            }
        }).then(function successCallback(response,countryCode) {
            if (errorHandler(response.data)) {
                console.log("cities come from ajax")
                cityCache[response.config.data.CountryCode] = response.data;
                console.log(cityCache)
                return response.data
            }
        });
    } else {
        vm.cityPromise = $timeout(function () {//I use this to get promise object
            return cityCache[countryCode]
        }, 0)
        console.log("cities comes from cache");
    }

    return vm.cityPromise;
}

实施例: 让我们说我在同一时间调用getCities函数3次。我正在通过chrome观看我的网络流量。我看到3个ajax调用。这很正常。但有时,我呼吁同一个城市。我需要编辑我的函数,该函数可以理解之前是否已调用城市数据(缓存类型)。
例如:如果我用这个论点要求函数3次:

1 - 给我德国的城市,
2 - 给我爱尔兰的城市,
3 - 给我德国的城市(再次),

它打了3次电话。但我想要1次打电话给德国,1次打电话给爱尔兰。只需2个电话。

4 个答案:

答案 0 :(得分:1)

与您的其他问题相同的答案,只需将国家/地区代码映射到承诺。 也和以前一样,考虑错误情况。

var vm = this;

vm.cityPromises = {};

function getCities(countryCode) {
    if (!vm.cityPromises[countryCode]) {
        vm.cityPromises[countryCode] = $http({
            method: 'POST',
            cache: true,
            url: API + '/api/Global/Countries',
        }).then(function successCallback(response) {
            if (errorHandler(response.data)) {
                console.log("ajax")
                return response.data;
            }
        });
    } else {
        console.log("cache")
    }
    return vm.cityPromises[countryCode];
}

答案 1 :(得分:0)

你可以在这里使用自己的承诺。不要忘记注入$ q服务。

var rp = require('request-promise');
var ids = [];


function runmyFunction() {
    if (ids.indexOf(12345)==-1){
   myFunction();
   }
}

function myFunction() {
    var options = {
    uri: 'someURI'
    , headers: {
        'User-Agent': 'Request-Promise'
    }
    , json: true
};
rp(options)
    .then(function (response,mids) {
        mids.push(response.data.id);
    }.bind(ids))
    .catch(function (err) {
       console.log(err);
    });
}

答案 2 :(得分:0)

尝试使用angular:{/ p>中的$q服务

已更新,以防止同一城市多次通话:

FIDDLE

服务:

.service("cityService", function($http, $q, $httpParamSerializerJQLike){
    //var callCache = {};
    var cityCache = {};
    return {
        getCities: function(countryCode){

            //if(callCache[countryCode] === undefined){
                  var promise = $q.defer();
           //     callCache[countryCode] = promise;
            //}else{
            //      console.log("return cached promise!!", callCache[countryCode]);
            //      return callCache[countryCode].promise;
            //}

            if (countryCode!=undefined && !cityCache[countryCode]) {
                    console.log("new city");
                var data = $httpParamSerializerJQLike({
                    json: JSON.stringify({
                        name: countryCode+Math.random().toString(36).substring(7)
                    })
                });
                $http({
                    method: 'POST',
                    url:"/echo/json/",
                    data: data
                }).then(function(risp) {
                        console.log("servicelog",risp.data);
                        cityCache[countryCode] = risp.data;
                    var obj = angular.extend({cache: false}, risp.data);
                    promise.resolve(obj);
                    //callCache[countryCode].resolve(obj);
                    //delete callCache[countryCode];
                });
            }else{
                setTimeout(function(){
                        var obj = angular.extend({cache: true}, cityCache[countryCode]);
                    promise.resolve(obj);
                    //callCache[countryCode].resolve(obj)
                    //delete callCache[countryCode];
                }, 1000)
            }
            return promise.promise;
        }
    }  
});

答案 3 :(得分:0)

我通过为承诺创建一个对象解决了我的问题,非常感谢@Luke Harper之前和现在帮助我:)他的答案也是正确的但我必须为我的应用添加更多代码。

如果您在我的代码中发现任何问题,请写信给我,以便我编辑答案

所以这是我的解决方案:

vm.cityPromise = {};
vm.getCities = function (countryCode) {
    vm.cityPromise["cityCache"] = countryCode;
    if (!vm.cityPromise[countryCode]) {
        if (countryCode != undefined && !cityCache[countryCode]) {
            vm.cityPromise[countryCode] = $http({
                method: 'POST',
                cache: true,
                url: API + '/api/Global/CountryCities',
                data: {
                    "CountryCode": countryCode
                }
            }).then(function successCallback(response, countryCode) {
                if (errorHandler(response.data)) {
                    cityCache[response.config.data.CountryCode] = response.data;
                    console.log("cities ajax, cityCache", cityCache)
                    return response.data
                }
            },function error (response){
                console.log ("error:",response)
            });
        } else {
            vm.cityPromise[countryCode] = $timeout(function () {
                return cityCache[countryCode]
            }, 0)
            console.log("getCities cache");
        }
    }
    return vm.cityPromise[countryCode];
}