Javascript 返回空对象的服务函数

Javascript 返回空对象的服务函数,javascript,angularjs,global-variables,Javascript,Angularjs,Global Variables,我有一个工厂函数,它不会返回我试图在控制器中设置的变量。我没有得到一个错误,只是变量不会被设置为它的假设 spApp.factory('SiteService', function ($q){ var rootUrl = window.location.protocol + "//" + window.location.hostname; var siteMap; //returns object containing info about all sites with

我有一个工厂函数,它不会返回我试图在控制器中设置的变量。我没有得到一个错误,只是变量不会被设置为它的假设

spApp.factory('SiteService', function ($q){
    var rootUrl = window.location.protocol + "//" + window.location.hostname;
    var siteMap;

    //returns object containing info about all sites within collection
    var getSiteMap = function () {
        siteMap = {};

        var promise = $().SPServices({
            operation: "GetAllSubWebCollection",
            async: true
        });

        promise.then(
            function (response){
                map = {}; //init the map
                var web = $(response).find("Web").map(function () {
                    return $(this).attr('Url');
                });
                var webTitle = $(response).find("Web").map(function () {
                    return $(this).attr('Title');
                });  

                // create map
                for (var i = 0; i < web.length; i++) {
                    var item = web[i],
                        title = webTitle[i],
                        parts = item.split('/'),
                        domain = parts.splice(0, 3).join('/'),
                        current;

                    if (!map[domain]) map[domain] = {url:domain, title:title ,children:{}};
                    current = map[domain].children;

                    for (var index in parts) {
                        var part = parts[index];
                        if (!current[part]) {
                            current[part] = {url:domain+'/'+parts.slice(0,index+1).join('/'), title:title, children:{}};
                        }
                        current = current[part].children;
                    }
                }
            siteMap = map;
        }, function(reason){
            alert('FAILED:' + reason);
        })
        console.log(siteMap);
        return siteMap;
    }

    return{
        getSiteMap:getSiteMap
    }
});

你所面临的问题是,你正在履行承诺。当您将console.log放在then函数之外时,您是在实际解析变量之前记录该变量

如果在分配sitemap后将console.log放入then函数中,它应该显示正确的值,但您仍然无法可靠地访问它

我认为,在站点地图值填充了数据之后,访问该值的最简单方法是传入回调函数。例如:

var getSiteMap = function (_callback) {
    siteMap = {};

    $().SPServices({
        operation: "GetAllSubWebCollection",
        async: true
    }).then(function(response){
        // Process the data and set siteMap
        // ...
        siteMap = map;

        // now pass siteMap to the callback
        _callback(siteMap);
    });
然后,您可以在控制器中这样使用:

SiteService.getSiteMap(function(sitemap){
    // Do something with your sitemap here
});

虽然这会奏效,但这只是一个简单的例子,并不一定是最好的方法。如果您不喜欢回调,您可以创建第二个承诺,该承诺仅在分配siteMap时才能解决。另外,根据getSiteMap的使用情况,您可能希望缓存该值,否则每次都会调用该请求。

尝试如下链接您的承诺:

var getSiteMap = function () {
    siteMap = {};

    var promise = $().SPServices({
        operation: "GetAllSubWebCollection",
        async: true
    });

     return promise.then(function(response){ //return your promise
        // all you code
        siteMap = map;

        return siteMap; //return a value to another .then in the chain
    });
 }
SiteService.getSiteMap().then(function(siteMap){

});
像这样使用它:

var getSiteMap = function () {
    siteMap = {};

    var promise = $().SPServices({
        operation: "GetAllSubWebCollection",
        async: true
    });

     return promise.then(function(response){ //return your promise
        // all you code
        siteMap = map;

        return siteMap; //return a value to another .then in the chain
    });
 }
SiteService.getSiteMap().then(function(siteMap){

});

看起来您正在检查您的变量,但承诺尚未解决。我尝试将返回值放入.then函数中,但这也不起作用。